diff -Nru proguard-6.0.3/annotations/build.gradle proguard-6.2.0/annotations/build.gradle --- proguard-6.0.3/annotations/build.gradle 2017-08-27 23:32:44.000000000 +0000 +++ proguard-6.2.0/annotations/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -2,6 +2,9 @@ apply plugin: 'java' +sourceCompatibility = "${target}" +targetCompatibility = "${target}" + sourceSets.main { java { srcDirs = ['src'] diff -Nru proguard-6.0.3/annotations/build.xml proguard-6.2.0/annotations/build.xml --- proguard-6.0.3/annotations/build.xml 2017-08-27 22:44:25.000000000 +0000 +++ proguard-6.2.0/annotations/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,6 +3,8 @@ + + @@ -17,6 +19,8 @@ diff -Nru proguard-6.0.3/annotations/gradle.properties proguard-6.2.0/annotations/gradle.properties --- proguard-6.0.3/annotations/gradle.properties 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/annotations/gradle.properties 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,3 @@ +# Gradle build properties for the ProGuard annotations. + +target = 1.8 diff -Nru proguard-6.0.3/annotations/pom.xml proguard-6.2.0/annotations/pom.xml --- proguard-6.0.3/annotations/pom.xml 2018-05-06 20:34:21.000000000 +0000 +++ proguard-6.2.0/annotations/pom.xml 2019-10-04 12:15:32.000000000 +0000 @@ -8,7 +8,7 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-annotations diff -Nru proguard-6.0.3/ant/build.gradle proguard-6.2.0/ant/build.gradle --- proguard-6.0.3/ant/build.gradle 2017-09-20 21:38:37.000000000 +0000 +++ proguard-6.2.0/ant/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -6,6 +6,9 @@ jcenter() } +sourceCompatibility = "${target}" +targetCompatibility = "${target}" + sourceSets.main { java { srcDirs = ['src'] diff -Nru proguard-6.0.3/ant/build.xml proguard-6.2.0/ant/build.xml --- proguard-6.0.3/ant/build.xml 2017-08-27 13:25:01.000000000 +0000 +++ proguard-6.2.0/ant/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,7 +3,8 @@ - + + @@ -25,6 +26,8 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-anttask diff -Nru proguard-6.0.3/ant/src/proguard/ant/ClassPathElement.java proguard-6.2.0/ant/src/proguard/ant/ClassPathElement.java --- proguard-6.0.3/ant/src/proguard/ant/ClassPathElement.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/ClassPathElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/ant/src/proguard/ant/ClassSpecificationElement.java proguard-6.2.0/ant/src/proguard/ant/ClassSpecificationElement.java --- proguard-6.0.3/ant/src/proguard/ant/ClassSpecificationElement.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/ClassSpecificationElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/ant/src/proguard/ant/ConfigurationElement.java proguard-6.2.0/ant/src/proguard/ant/ConfigurationElement.java --- proguard-6.0.3/ant/src/proguard/ant/ConfigurationElement.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/ConfigurationElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/ant/src/proguard/ant/ConfigurationTask.java proguard-6.2.0/ant/src/proguard/ant/ConfigurationTask.java --- proguard-6.0.3/ant/src/proguard/ant/ConfigurationTask.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/ConfigurationTask.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -73,6 +73,9 @@ configuration.assumeNoExternalReturnValues = extendClassSpecifications(configuration.assumeNoExternalReturnValues, this.configuration.assumeNoExternalReturnValues); + configuration.assumeValues = extendClassSpecifications(configuration.assumeValues, + this.configuration.assumeValues); + configuration.keepPackageNames = extendList(configuration.keepPackageNames, this.configuration.keepPackageNames); @@ -234,6 +237,13 @@ } + public void addConfiguredAssumevalues(ClassSpecificationElement classSpecificationElement) + { + configuration.assumeValues = extendClassSpecifications(configuration.assumeValues, + classSpecificationElement); + } + + public void addConfiguredOptimizations(FilterElement filterElement) { addConfiguredOptimization(filterElement); diff -Nru proguard-6.0.3/ant/src/proguard/ant/FilterElement.java proguard-6.2.0/ant/src/proguard/ant/FilterElement.java --- proguard-6.0.3/ant/src/proguard/ant/FilterElement.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/FilterElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/ant/src/proguard/ant/KeepSpecificationElement.java proguard-6.2.0/ant/src/proguard/ant/KeepSpecificationElement.java --- proguard-6.0.3/ant/src/proguard/ant/KeepSpecificationElement.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/KeepSpecificationElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/ant/src/proguard/ant/MemberSpecificationElement.java proguard-6.2.0/ant/src/proguard/ant/MemberSpecificationElement.java --- proguard-6.0.3/ant/src/proguard/ant/MemberSpecificationElement.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/MemberSpecificationElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,7 +22,7 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.types.DataType; -import proguard.MemberSpecification; +import proguard.*; import proguard.classfile.*; import proguard.classfile.util.ClassUtil; import proguard.util.ListUtil; @@ -41,6 +41,7 @@ private String type; private String name; private String parameters; + private String values; /** @@ -69,6 +70,7 @@ String annotation = memberSpecificationElement.annotation; String name = memberSpecificationElement.name; String parameters = memberSpecificationElement.parameters; + String values = memberSpecificationElement.values; // Perform some basic conversions and checks on the attributes. if (annotation != null) @@ -90,6 +92,11 @@ type = JavaConstants.TYPE_VOID; } + if (values != null) + { + throw new BuildException("Values attribute not allowed in constructor specification ["+values+"]"); + } + name = ClassConstants.METHOD_NAME_INIT; } else if ((type != null) ^ (parameters != null)) @@ -105,6 +112,14 @@ } } + if (values != null) + { + if (type == null) + { + throw new BuildException("Values attribute must be specified in combination with type attribute in class member specification ["+values+"]"); + } + } + List parameterList = ListUtil.commaSeparatedList(parameters); String descriptor = @@ -112,7 +127,15 @@ type != null ? ClassUtil.internalType(type) : null; - MemberSpecification memberSpecification = + MemberSpecification memberSpecification = values != null ? + new MemberValueSpecification(requiredAccessFlags(true, access), + requiredAccessFlags(false, access), + annotation, + name, + descriptor, + parseValues(type, + ClassUtil.internalType(type), + values)) : new MemberSpecification(requiredAccessFlags(true, access), requiredAccessFlags(false, access), annotation, @@ -165,6 +188,12 @@ } + public void setValues(String values) + { + this.values = values; + } + + // Small utility methods. private int requiredAccessFlags(boolean set, @@ -215,4 +244,98 @@ return accessFlags; } + + + /** + * Parses the given string as a value or value range of the given primitive + * type. For example, values "123" or "100..199" of type "int" ("I"). + */ + private Number[] parseValues(String externalType, + String internalType, + String string) + throws BuildException + { + int rangeIndex = string.lastIndexOf(".."); + return rangeIndex >= 0 ? + new Number[] + { + parseValue(externalType, internalType, string.substring(0, rangeIndex)), + parseValue(externalType, internalType, string.substring(rangeIndex + 2)) + } : + new Number[] + { + parseValue(externalType, internalType, string) + }; + } + + + /** + * Parses the given string as a value of the given primitive type. + * For example, value "123" of type "int" ("I"). + * For example, value "true" of type "boolean" ("Z"), returned as 1. + */ + private Number parseValue(String externalType, + String internalType, + String string) + throws BuildException + { + try + { + switch (internalType.charAt(0)) + { + case ClassConstants.TYPE_BOOLEAN: + { + return parseBoolean(string); + } + case ClassConstants.TYPE_BYTE: + case ClassConstants.TYPE_CHAR: + case ClassConstants.TYPE_SHORT: + case ClassConstants.TYPE_INT: + { + return Integer.decode(string); + } + //case ClassConstants.TYPE_LONG: + //{ + // return Long.decode(string); + //} + //case ClassConstants.TYPE_FLOAT: + //{ + // return Float.valueOf(string); + //} + //case ClassConstants.TYPE_DOUBLE: + //{ + // return Double.valueOf(string); + //} + default: + { + throw new BuildException("Can't handle '"+externalType+"' constant ["+string+"]"); + } + } + } + catch (NumberFormatException e) + { + throw new BuildException("Can't parse "+externalType+" constant ["+string+"]"); + } + } + + + /** + * Parses the given boolean string as an integer (0 or 1). + */ + private Integer parseBoolean(String string) + throws BuildException + { + if ("false".equals(string)) + { + return Integer.valueOf(0); + } + else if ("true".equals(string)) + { + return Integer.valueOf(1); + } + else + { + throw new BuildException("Unknown boolean constant ["+string+"]"); + } + } } diff -Nru proguard-6.0.3/ant/src/proguard/ant/ProGuardTask.java proguard-6.2.0/ant/src/proguard/ant/ProGuardTask.java --- proguard-6.0.3/ant/src/proguard/ant/ProGuardTask.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/ant/src/proguard/ant/ProGuardTask.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/buildscripts/ant.properties proguard-6.2.0/buildscripts/ant.properties --- proguard-6.0.3/buildscripts/ant.properties 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/buildscripts/ant.properties 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,3 @@ +# Ant build properties for ProGuard. + +target = 1.8 diff -Nru proguard-6.0.3/buildscripts/build.gradle proguard-6.2.0/buildscripts/build.gradle --- proguard-6.0.3/buildscripts/build.gradle 2017-09-20 21:39:48.000000000 +0000 +++ proguard-6.2.0/buildscripts/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -1,5 +1,12 @@ // Gradle build script for all ProGuard jars. +allprojects { + repositories { + google() + jcenter() + } +} + task clean { delete fileTree('../lib') } diff -Nru proguard-6.0.3/buildscripts/functions.mk proguard-6.2.0/buildscripts/functions.mk --- proguard-6.0.3/buildscripts/functions.mk 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/buildscripts/functions.mk 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,68 @@ +# Support functions for building ProGuard with make. + +SRC = src +OUT = out +LIB = ../lib + +JAVA_TARGET = 1.8 + +ifeq ($(CLASSPATH),) + CLASSPATH_OPTION = +else + CLASSPATH_OPTION = -classpath $(CLASSPATH) +endif + +TARGET_JAR = $(LIB)/$(TARGET).jar + +# Command to download dependencies. + +DOWNLOAD = wget -O +#DOWNLOAD = curl -L -o + +# Function to find the resource files of a given target. + +define RESOURCES + $(shell find $(SRC)/$(dir $(1)) -maxdepth 1 \( -name \*.properties -o -name \*.png -o -name \*.gif -o -name \*.pro \) -printf $(OUT)/$(dir $(1))%P\\n) +endef + +# Rules for creating the jars. + +all: $(TARGET_JAR) + +$(TARGET_JAR): $(OUT)/$(MAIN_CLASS).class $(LIB) +ifeq ($(UPDATE_JAR),true) + jar -uf $@ -C $(OUT) $(dir $(MAIN_CLASS)) +else +ifeq ($(INCLUDE_MANIFEST),true) + jar -cfm $@ $(SRC)/META-INF/MANIFEST.MF -C $(OUT) $(dir $(MAIN_CLASS)) +else + jar -cf $@ -C $(OUT) $(dir $(MAIN_CLASS)) +endif +endif + +$(TARGET_JAR): $(call RESOURCES,$(MAIN_CLASS)) + +# Rule for compiling the class files. + +$(OUT)/%.class: $(SRC)/%.java $(subst :, ,$(CLASSPATH)) $(OUT) + javac -nowarn -Xlint:none $(CLASSPATH_OPTION) -source $(JAVA_TARGET) -target $(JAVA_TARGET) -sourcepath $(SRC) -d $(OUT) $(filter %.java,$^) 2>&1 | sed -e 's|^| |' + +# Rule for copying the resource files. + +$(OUT)/%.properties $(OUT)/%.png $(OUT)/%.gif $(OUT)/%.pro: + cp $(subst $(OUT),$(SRC),$@) $@ + +# Rule for creating output directories. + +$(OUT) $(LIB): + mkdir -p $@ + +# Rule for dependencies on other modules. + +../%/$(OUT): + cd $(dir $@) && $(MAKE) + +clean: + rm -fr $(OUT) + +.PHONY: all clean diff -Nru proguard-6.0.3/buildscripts/functions.sh proguard-6.2.0/buildscripts/functions.sh --- proguard-6.0.3/buildscripts/functions.sh 2017-09-17 20:06:32.000000000 +0000 +++ proguard-6.2.0/buildscripts/functions.sh 2019-09-18 11:52:51.000000000 +0000 @@ -6,6 +6,8 @@ OUT=out LIB=../lib +TARGET=1.8 + PROGUARD_JAR=$LIB/proguard.jar RETRACE_JAR=$LIB/retrace.jar PROGUARD_GUI_JAR=$LIB/proguardgui.jar @@ -13,11 +15,25 @@ set -o pipefail +function download { + if [ ! -f "$2" ]; then + echo "Downloading $2..." + if type wget > /dev/null 2>&1; then + wget -O "$2" "$1" + else + curl -L -o "$2" "$1" + fi + fi +} + function compile { # Compile java source files. echo "Compiling $(basename $PWD) ($1)..." mkdir -p "$OUT" && \ - javac -nowarn -Xlint:none -sourcepath "$SRC" -d "$OUT" \ + javac -nowarn -Xlint:none -source $TARGET -target $TARGET \ + -sourcepath "$SRC" -d "$OUT" \ + ${2:+-classpath "$2"} \ + `find $SRC -name _*.java` \ "$SRC"/${1//.//}.java 2>&1 \ | sed -e 's|^| |' || return 1 @@ -30,6 +46,7 @@ function createjar { echo "Creating $1..." + mkdir -p $(dirname "$1") && \ if [ -f "$SRC/META-INF/MANIFEST.MF" ]; then jar -cfm "$1" "$SRC/META-INF/MANIFEST.MF" -C "$OUT" proguard else diff -Nru proguard-6.0.3/buildscripts/gradle.properties proguard-6.2.0/buildscripts/gradle.properties --- proguard-6.0.3/buildscripts/gradle.properties 2017-08-19 23:18:25.000000000 +0000 +++ proguard-6.2.0/buildscripts/gradle.properties 2019-09-18 11:52:51.000000000 +0000 @@ -1 +1,5 @@ +# Gradle build properties for all ProGuard jars. + +target = 1.8 + wtkDir=/usr/local/java/wtk2.1 diff -Nru proguard-6.0.3/buildscripts/pom.xml proguard-6.2.0/buildscripts/pom.xml --- proguard-6.0.3/buildscripts/pom.xml 2018-05-06 20:34:21.000000000 +0000 +++ proguard-6.2.0/buildscripts/pom.xml 2019-10-04 12:15:32.000000000 +0000 @@ -7,11 +7,11 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 pom [${project.groupId}] ${project.artifactId} ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. - http://proguard.sourceforge.net/ + https://www.guardsquare.com/proguard 3 @@ -21,9 +21,9 @@ lafortune Eric Lafortune - http://www.lafortune.eu/ - GuardSquare - http://www.guardsquare.com/ + https://www.lafortune.eu/ + Guardsquare + https://www.guardsquare.com/ Project Administrator Developer @@ -34,19 +34,19 @@ GNU General Public License, Version 2 - http://www.gnu.org/licenses/gpl-2.0.txt + https://www.gnu.org/licenses/gpl-2.0.txt repo SourceForge.net Tracker - http://sourceforge.net/p/proguard/bugs/ + https://sourceforge.net/p/proguard/bugs/ - http://hg.code.sf.net/p/proguard/code - scm:hg:http://hg.code.sf.net/p/proguard/code + https://hg.code.sf.net/p/proguard/code + scm:hg:https://hg.code.sf.net/p/proguard/code @@ -70,8 +70,8 @@ maven-compiler-plugin 3.5.1 - 1.5 - 1.5 + 1.8 + 1.8 @@ -80,7 +80,7 @@ 2.9.1 - http://download.oracle.com/javase/1.5.0/docs/api/ + https://download.oracle.com/javase/1.5.0/docs/api/ true diff -Nru proguard-6.0.3/buildscripts/README proguard-6.2.0/buildscripts/README --- proguard-6.0.3/buildscripts/README 2018-01-11 21:58:15.000000000 +0000 +++ proguard-6.2.0/buildscripts/README 2019-09-18 11:52:51.000000000 +0000 @@ -27,4 +27,4 @@ https://www.guardsquare.com/proguard -Copyright (c) 2002-2018 Eric Lafortune @ GuardSquare +Copyright (c) 2002-2019 Eric Lafortune @ GuardSquare diff -Nru proguard-6.0.3/core/ant.properties proguard-6.2.0/core/ant.properties --- proguard-6.0.3/core/ant.properties 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/ant.properties 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,3 @@ +# Ant build properties for ProGuard. + +gson.version = 2.8.5 diff -Nru proguard-6.0.3/core/build.gradle proguard-6.2.0/core/build.gradle --- proguard-6.0.3/core/build.gradle 2017-08-27 13:29:04.000000000 +0000 +++ proguard-6.2.0/core/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -2,6 +2,13 @@ apply plugin: 'java' +repositories { + jcenter() +} + +sourceCompatibility = "${target}" +targetCompatibility = "${target}" + sourceSets.main { java { srcDirs = ['src'] @@ -18,3 +25,8 @@ jar { manifest.from 'src/META-INF/MANIFEST.MF' } + + +dependencies { + compile "com.google.code.gson:gson:${gsonVersion}" +} diff -Nru proguard-6.0.3/core/build.sh proguard-6.2.0/core/build.sh --- proguard-6.0.3/core/build.sh 2017-09-16 22:50:47.000000000 +0000 +++ proguard-6.2.0/core/build.sh 2019-09-18 11:52:51.000000000 +0000 @@ -8,5 +8,10 @@ MAIN_CLASS=proguard.ProGuard -compile $MAIN_CLASS && \ +GSON_VERSION=2.8.5 +GSON_URL=https://jcenter.bintray.com/com/google/code/gson/gson/${GSON_VERSION}/gson-${GSON_VERSION}.jar +GSON_JAR=$LIB/gson-${GSON_VERSION}.jar + +download "$GSON_URL" "$GSON_JAR" && \ +compile $MAIN_CLASS "$GSON_JAR" && \ createjar "$PROGUARD_JAR" || exit 1 diff -Nru proguard-6.0.3/core/build.xml proguard-6.2.0/core/build.xml --- proguard-6.0.3/core/build.xml 2017-08-27 12:39:11.000000000 +0000 +++ proguard-6.2.0/core/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,6 +3,9 @@ + + + @@ -13,12 +16,21 @@ - + + + + + diff -Nru proguard-6.0.3/core/gradle.properties proguard-6.2.0/core/gradle.properties --- proguard-6.0.3/core/gradle.properties 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/gradle.properties 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,5 @@ +# Gradle build properties for ProGuard. + +target = 1.8 + +gsonVersion = 2.8.5 diff -Nru proguard-6.0.3/core/makefile proguard-6.2.0/core/makefile --- proguard-6.0.3/core/makefile 2017-09-17 21:43:57.000000000 +0000 +++ proguard-6.2.0/core/makefile 2019-09-18 11:52:51.000000000 +0000 @@ -1,8 +1,15 @@ # GNU/Linux makefile for ProGuard. +GSON_VERSION = 2.8.5 +GSON_URL = https://jcenter.bintray.com/com/google/code/gson/gson/${GSON_VERSION}/gson-${GSON_VERSION}.jar +GSON_JAR = $(LIB)/gson-${GSON_VERSION}.jar + MAIN_CLASS = proguard/ProGuard -CLASSPATH = +CLASSPATH = $(GSON_JAR) TARGET = proguard INCLUDE_MANIFEST = true include ../buildscripts/functions.mk + +$(GSON_JAR): + $(DOWNLOAD) $(GSON_JAR) $(GSON_URL) diff -Nru proguard-6.0.3/core/pom.xml proguard-6.2.0/core/pom.xml --- proguard-6.0.3/core/pom.xml 2018-05-06 20:34:22.000000000 +0000 +++ proguard-6.2.0/core/pom.xml 2019-10-04 12:15:32.000000000 +0000 @@ -8,7 +8,7 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-base @@ -38,4 +38,19 @@ + + + + com.google.code.gson + gson + 2.8.5 + provided + + + + + jcenter + https://jcenter.bintray.com + + diff -Nru proguard-6.0.3/core/src/proguard/ArgumentWordReader.java proguard-6.2.0/core/src/proguard/ArgumentWordReader.java --- proguard-6.0.3/core/src/proguard/ArgumentWordReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ArgumentWordReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/AssumeNoSideEffectsChecker.java proguard-6.2.0/core/src/proguard/AssumeNoSideEffectsChecker.java --- proguard-6.0.3/core/src/proguard/AssumeNoSideEffectsChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/AssumeNoSideEffectsChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/backport/AbstractAPIConverter.java proguard-6.2.0/core/src/proguard/backport/AbstractAPIConverter.java --- proguard-6.0.3/core/src/proguard/backport/AbstractAPIConverter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/AbstractAPIConverter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,910 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.*; +import proguard.classfile.editor.*; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.util.*; + +/** + * Abstract base class for API converter implementations. + *

+ * By default, this class acts as ClassVisitor and will replace any + * occurrence of the specified methods / types as configured by the + * actual implementation. + * + * @see StreamSupportConverter + * @see JSR310Converter + * + * @author Thomas Neidhart + */ +class AbstractAPIConverter +extends SimplifiedVisitor +implements ClassVisitor, + + // Implementation interfaces. + MemberVisitor, + AttributeVisitor, + InstructionVisitor, + ConstantVisitor, + LocalVariableInfoVisitor, + LocalVariableTypeInfoVisitor, + AnnotationVisitor, + ElementValueVisitor +{ + private static final boolean DEBUG = false; + + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final WarningPrinter warningPrinter; + private final ClassVisitor modifiedClassVisitor; + private final InstructionVisitor extraInstructionVisitor; + + private TypeReplacement[] typeReplacements; + private MethodReplacement[] methodReplacements; + + private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(true, true); + private ConstantPoolEditor constantPoolEditor; + + private int referencingOffset; + private Method referencingMethod; + private boolean classModified; + private boolean instructionReplaced; + + + /** + * Create a new AbstractAPIConverter instance. + */ + AbstractAPIConverter(ClassPool programClassPool, + ClassPool libraryClassPool, + WarningPrinter warningPrinter, + ClassVisitor modifiedClassVisitor, + InstructionVisitor extraInstructionVisitor) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.warningPrinter = warningPrinter; + this.modifiedClassVisitor = modifiedClassVisitor; + this.extraInstructionVisitor = extraInstructionVisitor; + } + + + protected MethodReplacement replace(String className, + String methodName, + String methodDesc, + String replacementClassName, + String replacementMethodName, + String replacementMethodDesc) + { + MethodReplacement methodReplacement = + new MethodReplacement(className, methodName, methodDesc, + replacementClassName, replacementMethodName, replacementMethodDesc); + + return methodReplacement.isValid() ? + methodReplacement : + missing(className, methodName, methodDesc); + } + + + protected TypeReplacement replace(String className, String replacementClassName) + { + TypeReplacement typeReplacement = + new TypeReplacement(className, replacementClassName); + + return typeReplacement.isValid() ? + typeReplacement : + missing(className); + } + + + protected MethodReplacement missing(String className, String methodName, String methodDesc) + { + return new MissingMethodReplacement(className, methodName, methodDesc); + } + + + protected TypeReplacement missing(String className) + { + return new MissingTypeReplacement(className); + } + + + protected void setTypeReplacements(TypeReplacement[] replacements) + { + this.typeReplacements = replacements; + } + + + protected void setMethodReplacements(MethodReplacement[] replacements) + { + this.methodReplacements = replacements; + } + + + // Implementations for ClassVisitor. + + @Override + public void visitAnyClass(Clazz clazz) {} + + + @Override + public void visitProgramClass(ProgramClass programClass) + { + constantPoolEditor = new ConstantPoolEditor(programClass); + + classModified = false; + + // We need to update the code attributes first. + programClass.methodsAccept( + new AllAttributeVisitor( + new AttributeNameFilter(ClassConstants.ATTR_Code, + this))); + + // Update the class constants directly. + programClass.constantPoolEntriesAccept( + new ConstantTagFilter(ClassConstants.CONSTANT_Class, + this)); + + // Update descriptors and attributes of fields and methods. + programClass.fieldsAccept(this); + programClass.methodsAccept(this); + + // Update the class attributes. + programClass.attributesAccept(this); + + if (classModified) + { + // Remove replaced and now unused constant pool entries. + programClass.accept(new ConstantPoolShrinker()); + + if (modifiedClassVisitor != null) + { + // Mark this class as being modified. + modifiedClassVisitor.visitProgramClass(programClass); + } + } + } + + + // Implementations for MemberVisitor. + + @Override + public void visitAnyMember(Clazz clazz, Member member) {} + + + @Override + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + programField.u2descriptorIndex = updateDescriptor(programClass, programField.u2descriptorIndex); + + programField.attributesAccept(programClass, this); + } + + + @Override + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + programMethod.u2descriptorIndex = updateDescriptor(programClass, programMethod.u2descriptorIndex); + + // Update the remaining attributes, except for the code attribute, + // which has already been updated. + programMethod.attributesAccept(programClass, + new AttributeNameFilter("!" + ClassConstants.ATTR_Code, + this)); + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + + codeAttribute.instructionsAccept(clazz, method, this); + + if (codeAttributeEditor.isModified()) + { + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + + // Update the nested attributes. + codeAttribute.attributesAccept(clazz, method, this); + } + + + @Override + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + } + + + @Override + public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) + { + localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); + } + + + @Override + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + signatureAttribute.u2signatureIndex = updateDescriptor(clazz, signatureAttribute.u2signatureIndex); + } + + + @Override + public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) + { + annotationsAttribute.annotationsAccept(clazz, this); + } + + + @Override + public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) + { + parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); + } + + + @Override + public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) + { + annotationDefaultAttribute.defaultValueAccept(clazz, this); + } + + + // Implementations for LocalVariableInfoVisitor. + + @Override + public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) + { + localVariableInfo.u2descriptorIndex = updateDescriptor(clazz, localVariableInfo.u2descriptorIndex); + } + + + // Implementations for LocalVariableTypeInfoVisitor. + + @Override + public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) + { + localVariableTypeInfo.u2signatureIndex = updateDescriptor(clazz, localVariableTypeInfo.u2signatureIndex); + } + + + // Implementations for AnnotationVisitor. + + @Override + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + annotation.u2typeIndex = updateDescriptor(clazz, annotation.u2typeIndex); + + annotation.elementValuesAccept(clazz, this); + } + + + // Implementations for ElementValueVisitor. + + @Override + public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) {} + + + @Override + public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) + { + enumConstantElementValue.u2typeNameIndex = updateDescriptor(clazz, enumConstantElementValue.u2typeNameIndex); + } + + + @Override + public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) + { + String className = classElementValue.getClassName(clazz); + String newClassName = replaceClassName(clazz, className); + if (!newClassName.equals(className)) + { + classModified = true; + classElementValue.u2classInfoIndex = constantPoolEditor.addUtf8Constant(newClassName); + } + } + + + @Override + public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) + { + annotationElementValue.annotationAccept(clazz, this); + } + + + @Override + public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) + { + arrayElementValue.elementValuesAccept(clazz, annotation, this); + } + + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + @Override + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + switch (constantInstruction.opcode) + { + case InstructionConstants.OP_INVOKEVIRTUAL: + case InstructionConstants.OP_INVOKESPECIAL: + case InstructionConstants.OP_INVOKEINTERFACE: + case InstructionConstants.OP_INVOKESTATIC: + this.referencingOffset = offset; + this.referencingMethod = method; + this.instructionReplaced = false; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + + if (instructionReplaced && + extraInstructionVisitor != null) + { + extraInstructionVisitor.visitConstantInstruction(clazz, method, codeAttribute, offset, constantInstruction); + } + break; + + case InstructionConstants.OP_PUTFIELD: + case InstructionConstants.OP_GETFIELD: + case InstructionConstants.OP_PUTSTATIC: + case InstructionConstants.OP_GETSTATIC: + this.referencingOffset = offset; + this.referencingMethod = method; + this.instructionReplaced = false; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + + if (instructionReplaced && + extraInstructionVisitor != null) + { + extraInstructionVisitor.visitConstantInstruction(clazz, method, codeAttribute, offset, constantInstruction); + } + break; + } + } + + + // Implementations for ConstantVisitor. + + @Override + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + @Override + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + String className = classConstant.getName(clazz); + String newClassName = replaceClassName(clazz, className); + if (!newClassName.equals(className)) + { + classConstant.u2nameIndex = constantPoolEditor.addUtf8Constant(newClassName); + classModified = true; + } + } + + + @Override + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + { + String name = fieldrefConstant.getName(clazz); + String desc = fieldrefConstant.getType(clazz); + + String newDesc = replaceDescriptor(clazz, desc); + if (!newDesc.equals(desc)) + { + fieldrefConstant.u2nameAndTypeIndex = + constantPoolEditor.addNameAndTypeConstant(name, newDesc); + classModified = true; + } + } + + + @Override + public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) + { + if (!replaceMethodInvocation(referencingOffset, clazz, referencingMethod, refConstant)) + { + // If the method invocation was not replaced, we still + // have to replace the descriptor if necessary. + + String name = refConstant.getName(clazz); + String desc = refConstant.getType(clazz); + + String newDesc = replaceDescriptor(clazz, desc); + if (!newDesc.equals(desc)) + { + refConstant.u2nameAndTypeIndex = + constantPoolEditor.addNameAndTypeConstant(name, newDesc); + classModified = true; + } + } + } + + + // Private utility methods. + + /** + * Checks all the configured type replacements and replaces the given + * class name accordingly. + */ + private String replaceClassName(Clazz clazz, String className) + { + for (TypeReplacement typeReplacement : typeReplacements) + { + String newClassName = + typeReplacement.matchesClassName(className) ? + typeReplacement.replaceClassName(clazz, className) : + null; + + if (newClassName != null) + { + return newClassName; + } + } + + return className; + } + + + /** + * Replaces all class types that appear in the given descriptor. + */ + private String replaceDescriptor(Clazz clazz, String descriptor) + { + DescriptorClassEnumeration descriptorClassEnumeration = + new DescriptorClassEnumeration(descriptor); + + StringBuilder newDescriptorBuilder = new StringBuilder(descriptor.length()); + newDescriptorBuilder.append(descriptorClassEnumeration.nextFluff()); + + while (descriptorClassEnumeration.hasMoreClassNames()) + { + String className = descriptorClassEnumeration.nextClassName(); + String fluff = descriptorClassEnumeration.nextFluff(); + + newDescriptorBuilder.append(replaceClassName(clazz, className)); + newDescriptorBuilder.append(fluff); + } + + return newDescriptorBuilder.toString(); + } + + + /** + * Returns an updated descriptor index if the descriptor + * has changed. + */ + private int updateDescriptor(Clazz clazz, int descriptorIndex) + { + String descriptor = clazz.getString(descriptorIndex); + String newDescriptor = replaceDescriptor(clazz, descriptor); + if (!newDescriptor.equals(descriptor)) + { + classModified = true; + return constantPoolEditor.addUtf8Constant(newDescriptor); + } + else + { + return descriptorIndex; + } + } + + + /** + * Checks if the instruction at the given offset has to be replaced and + * modifies the code attribute accordingly. + */ + private boolean replaceMethodInvocation(int offset, Clazz clazz, Method method, RefConstant refConstant) + { + for (MethodReplacement methodReplacement : methodReplacements) + { + if (methodReplacement.matches(clazz, refConstant)) + { + methodReplacement.replaceInstruction(offset, clazz, method, refConstant); + classModified = true; + instructionReplaced = true; + return true; + } + } + return false; + } + + + // Private helper classes. + + /** + * Abstract base class for type and method replacement helper classes. + * Contains useful methods to avoid duplication. + */ + private abstract class AbstractReplacement + { + boolean isStatic(Member member) + { + return (member.getAccessFlags() & ClassConstants.ACC_STATIC) != 0; + } + + boolean isDefaultMethod(Clazz clazz, Member member) + { + return + isInterface(clazz) && + (member.getAccessFlags() & ClassConstants.ACC_ABSTRACT) == 0; + } + + boolean isInterface(Clazz clazz) + { + return (clazz.getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0; + } + + Clazz findReferencedClass(String className) + { + Clazz clazz = programClassPool.getClass(className); + return clazz != null ? clazz : libraryClassPool.getClass(className); + } + + Method findReferencedMethod(Clazz clazz, String methodName, String methodDescriptor) + { + return clazz.findMethod(methodName, methodDescriptor); + } + + String getReplacement(String original, String actual, String replacement) + { + if (replacement.contains("<1>")) + { + if (original.equals("") || + original.equals("")) + { + return actual; + } + + int wildcardIndex = original.indexOf("*"); + if (wildcardIndex != -1) + { + String match = actual.substring(wildcardIndex); + int replacementIndex = replacement.indexOf("<1>"); + return replacement.substring(0, replacementIndex) + match; + } + else + { + return original; + } + } + else + { + return replacement; + } + } + } + + + /** + * A helper class to define a needed method invocation replacement in an efficient way. + */ + protected class MethodReplacement extends AbstractReplacement + { + final String matchingClassName; + final String matchingMethodName; + final String matchingMethodDesc; + + final String replacementClassName; + final String replacementMethodName; + final String replacementMethodDesc; + + final StringMatcher classNameMatcher; + final StringMatcher methodNameMatcher; + final StringMatcher descMatcher; + + + MethodReplacement(String className, String methodName, String methodDesc, + String replacementClassName, String replacementMethodName, String replacementMethodDesc) + { + this.matchingClassName = className; + this.matchingMethodName = methodName; + this.matchingMethodDesc = methodDesc; + + this.replacementClassName = replacementClassName; + this.replacementMethodName = replacementMethodName; + this.replacementMethodDesc = replacementMethodDesc; + + classNameMatcher = new ClassNameParser(null).parse(matchingClassName); + methodNameMatcher = new NameParser(null).parse(matchingMethodName); + descMatcher = matchingMethodDesc.equals("**") ? + new ConstantMatcher(true) : + new ClassNameParser(null).parse(matchingMethodDesc); + } + + + private boolean isValid() + { + return replacementClassName.contains("*") || + replacementClassName.contains("<1>") || + findReferencedClass(replacementClassName) != null; + } + + + private String getDescReplacement(String original, String actual, String replacement) + { + if (matchingMethodName.equals("")) + { + // Extend the replacement descriptor. + String replacedDesc = getReplacement(original, actual, replacement); + return "(" + ClassUtil.internalTypeFromClassName(matchingClassName) + replacedDesc.substring(1); + } + else + { + return getReplacement(original, actual, replacement); + } + } + + + boolean matches(Clazz clazz, RefConstant methodrefConstant) + { + String className = methodrefConstant.getClassName(clazz); + String methodName = methodrefConstant.getName(clazz); + String methodDesc = methodrefConstant.getType(clazz); + + // Get the referenced class for the matching className. + // Might be null for wildcard classNames. + Clazz referencedMatchingClass = findReferencedClass(matchingClassName); + + Clazz referencedClass = methodrefConstant.referencedClass; + + if (referencedClass == null) + { + // Might happen if the project is not setup correctly. + // The class to be replaced is not present. + return false; + } + + Member referencedMember = methodrefConstant.referencedMember; + + if (referencedMember == null) + { + // Might happen if the project is not setup correctly. + // The method to be replaced is not present. + return false; + } + + return classPatternMatches(className, referencedClass, referencedMatchingClass) && + methodPatternMatches(methodName, referencedClass, referencedMember) && + descPatternMatches(methodDesc); + } + + + private boolean classPatternMatches(String className, Clazz referencedClazz, Clazz referencedMatchingClass) + { + return classNameMatcher.matches(className) || + (referencedClazz != null && referencedClazz.extendsOrImplements(referencedMatchingClass)); + } + + + private boolean methodPatternMatches(String methodName, Clazz referencedClass, Member referencedMember) + { + return methodNameMatcher.matches(methodName) || + // or the method is a default method and the pattern matches all default methods + (matchingMethodName.equals("") && isDefaultMethod(referencedClass, referencedMember)) || + // or the method is static and the pattern matches all static methods + (matchingMethodName.equals("") && isStatic(referencedMember)); + } + + + private boolean descPatternMatches(String methodDesc) + { + return descMatcher.matches(methodDesc); + } + + + void replaceInstruction(int offset, Clazz clazz, Method method, RefConstant refConstant) + { + String className = + getReplacement(matchingClassName, refConstant.getClassName(clazz), replacementClassName); + String methodName = + getReplacement(matchingMethodName, refConstant.getName(clazz), replacementMethodName); + String methodDesc = + getDescReplacement(matchingMethodDesc, refConstant.getType(clazz), replacementMethodDesc); + + methodDesc = replaceDescriptor(clazz, methodDesc); + + Clazz referencedClass = findReferencedClass(className); + if (referencedClass == null) + { + // Might happen if the project is not setup correctly. + // The class to be replaced is not present. + return; + } + + Method referencedMethod = findReferencedMethod(referencedClass, + methodName, + methodDesc); + if (referencedMethod == null) + { + warningPrinter.print(clazz.getName(), + className, + String.format("Warning: could not find replacement method '%s.%s(%s)',\n" + + " not converting method instruction at offset %d " + + "in method '%s.%s(%s)'.", + ClassUtil.externalClassName(className), + methodName, + ClassUtil.externalMethodArguments(methodDesc), + offset, + ClassUtil.externalClassName(clazz.getName()), + method.getName(clazz), + ClassUtil.externalMethodArguments(method.getDescriptor(clazz)))); + return; + } + + boolean isInterfaceMethod = isInterface(referencedClass); + byte replacementInstructionOpcode = isStatic(referencedMethod) ? + InstructionConstants.OP_INVOKESTATIC : + isInterfaceMethod ? + InstructionConstants.OP_INVOKEINTERFACE : + InstructionConstants.OP_INVOKEVIRTUAL; + + int methodConstant = + isInterfaceMethod ? + constantPoolEditor.addInterfaceMethodrefConstant(className, + methodName, + methodDesc, + referencedClass, + referencedMethod) : + constantPoolEditor.addMethodrefConstant(className, + methodName, + methodDesc, + referencedClass, + referencedMethod); + + codeAttributeEditor.replaceInstruction(offset, + new ConstantInstruction(replacementInstructionOpcode, + methodConstant)); + + if (DEBUG) + { + System.out.println(String.format("Replacing instruction at offset %d: %s.%s%s -> %s.%s%s", + offset, + refConstant.getClassName(clazz), + refConstant.getName(clazz), + refConstant.getType(clazz), + className, + methodName, + methodDesc)); + } + } + } + + + private class MissingMethodReplacement extends MethodReplacement + { + MissingMethodReplacement(String className, String methodName, String methodDesc) + { + super(className, methodName, methodDesc, null, null, null); + } + + + boolean isValid() + { + return false; + } + + + void replaceInstruction(int offset, Clazz clazz, Method method, RefConstant refConstant) + { + String className = refConstant.getClassName(clazz); + String methodName = refConstant.getName(clazz); + String methodDesc = refConstant.getType(clazz); + + warningPrinter.print(clazz.getName(), + String.format("Warning: no replacement available for '%s.%s(%s)'\n" + + " found at offset %d in method '%s.%s(%s)'.", + ClassUtil.externalClassName(className), + methodName, + ClassUtil.externalMethodArguments(methodDesc), + offset, + ClassUtil.externalClassName(clazz.getName()), + method.getName(clazz), + ClassUtil.externalMethodArguments(method.getDescriptor(clazz)))); + } + } + + + /** + * A helper class to define a needed type replacement in an efficient way. + */ + protected class TypeReplacement extends AbstractReplacement + { + final String matchingClassName; + final String replacementClassName; + final StringMatcher classNameMatcher; + + + TypeReplacement(String matchingClassName, String replacementClassName) + { + this.matchingClassName = matchingClassName; + this.replacementClassName = replacementClassName; + this.classNameMatcher = new ClassNameParser(null).parse(matchingClassName); + } + + + boolean isValid() + { + return replacementClassName.contains("*") || + replacementClassName.contains("<1>") || + findReferencedClass(replacementClassName) != null; + } + + + boolean matchesClassName(String className) + { + return classNameMatcher.matches(className); + } + + + String replaceClassName(Clazz clazz, String className) + { + return getReplacement(matchingClassName, className, replacementClassName); + } + } + + + private class MissingTypeReplacement extends TypeReplacement + { + MissingTypeReplacement(String className) + { + super(className, null); + } + + + boolean isValid() + { + return false; + } + + + String replaceClassName(Clazz clazz, String className) + { + warningPrinter.print(clazz.getName(), + String.format("Warning: no replacement available for class '%s'\n" + + " found in class '%s'.", + ClassUtil.externalClassName(className), + ClassUtil.externalClassName(clazz.getName()))); + + return className; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/backport/Backporter.java proguard-6.2.0/core/src/proguard/backport/Backporter.java --- proguard-6.0.3/core/src/proguard/backport/Backporter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/Backporter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -27,11 +27,13 @@ import proguard.classfile.editor.*; import proguard.classfile.instruction.Instruction; import proguard.classfile.instruction.visitor.InstructionCounter; -import proguard.classfile.util.ClassReferenceInitializer; +import proguard.classfile.util.*; import proguard.classfile.visitor.*; import proguard.optimize.peephole.*; import proguard.util.MultiValueMap; +import java.io.PrintWriter; + /** * This class backports classes to the specified targetClassVersion. * @@ -59,15 +61,19 @@ System.out.println("Backporting class files..."); } + PrintWriter err = new PrintWriter(System.err, true); + // Clean up any previous visitor info. programClassPool.classesAccept(new ClassCleaner()); libraryClassPool.classesAccept(new ClassCleaner()); - final InstructionCounter replacedStringConcatCounter = new InstructionCounter(); - final ClassCounter lambdaExpressionCounter = new ClassCounter(); - final MemberCounter staticInterfaceMethodCounter = new MemberCounter(); - final MemberCounter defaultInterfaceMethodCounter = new MemberCounter(); - final InstructionCounter replacedMethodCallCounter = new InstructionCounter(); + final InstructionCounter replacedStringConcatCounter = new InstructionCounter(); + final ClassCounter lambdaExpressionCounter = new ClassCounter(); + final MemberCounter staticInterfaceMethodCounter = new MemberCounter(); + final MemberCounter defaultInterfaceMethodCounter = new MemberCounter(); + final InstructionCounter replacedMethodCallCounter = new InstructionCounter(); + final InstructionCounter replacedStreamsMethodCallCounter = new InstructionCounter(); + final InstructionCounter replacedTimeMethodCallCounter = new InstructionCounter(); if (targetClassVersion < ClassConstants.CLASS_VERSION_1_9) { @@ -82,7 +88,6 @@ new AllMethodVisitor( new AllAttributeVisitor( new PeepholeOptimizer(codeAttributeEditor, - // Replace the indy instructions related to String concatenation. new StringConcatenationConverter(replacedStringConcatCounter, codeAttributeEditor))) @@ -102,11 +107,11 @@ // and convert lambda expressions and method references. ClassPool filteredClasses = new ClassPool(); programClassPool.classesAccept( - new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_8, - new AllAttributeVisitor( - new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods, - new AttributeToClassVisitor( - new ClassPoolFiller(filteredClasses)))))); + new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_8, + new AllAttributeVisitor( + new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods, + new AttributeToClassVisitor( + new ClassPoolFiller(filteredClasses)))))); // Note: we visit the filtered classes in a separate step // because we modify the programClassPool while converting @@ -114,9 +119,9 @@ new MultiClassVisitor( // Replace the indy instructions related to lambda expressions. new LambdaExpressionConverter(programClassPool, - libraryClassPool, - injectedClassNameMap, - lambdaExpressionCounter), + libraryClassPool, + injectedClassNameMap, + lambdaExpressionCounter), // Clean up unused bootstrap methods and their dangling constants. new BootstrapMethodsAttributeShrinker(), @@ -211,6 +216,100 @@ replacedMethodCallCounter))))); } + if (targetClassVersion < ClassConstants.CLASS_VERSION_1_8) + { + // Sanity check: if the streamsupport library is not found in the + // classpools do not try to backport. + ClassCounter streamSupportClasses = new ClassCounter(); + + ClassVisitor streamSupportVisitor = + new ClassNameFilter("java8/**", + streamSupportClasses); + + programClassPool.classesAccept(streamSupportVisitor); + libraryClassPool.classesAccept(streamSupportVisitor); + + if (streamSupportClasses.getCount() > 0) + { + WarningPrinter streamSupportWarningPrinter = + new WarningPrinter(err, configuration.warn); + + ClassPool modifiedClasses = new ClassPool(); + ClassVisitor modifiedClassCollector = + new ClassPoolFiller(modifiedClasses); + + programClassPool.classesAccept( + // Do not process classes of the stream support library itself. + new ClassNameFilter("!java8/**", + new StreamSupportConverter(programClassPool, + libraryClassPool, + streamSupportWarningPrinter, + modifiedClassCollector, + replacedStreamsMethodCallCounter))); + + // Re-Initialize references in modified classes. + modifiedClasses.classesAccept( + new ClassReferenceInitializer(programClassPool, + libraryClassPool)); + + int conversionWarningCount = streamSupportWarningPrinter.getWarningCount(); + if (conversionWarningCount > 0) + { + err.println("Warning: there were " + conversionWarningCount + + " Java 8 stream API method calls that could not be backported."); + err.println(" You should check if a your project setup is correct (compileSdkVersion, streamsupport dependency)."); + err.println(" For more information, consult the section \'Integration->Gradle Plugin->Java 8 stream API support\' in our manual"); + } + } + } + + if (targetClassVersion < ClassConstants.CLASS_VERSION_1_8) + { + // Sanity check: if the threetenbp library is not found in the + // classpools do not try to backport. + ClassCounter threetenClasses = new ClassCounter(); + + ClassVisitor threetenClassVisitor = + new ClassNameFilter("org/threeten/bp/**", + threetenClasses); + + programClassPool.classesAccept(threetenClassVisitor); + libraryClassPool.classesAccept(threetenClassVisitor); + + if (threetenClasses.getCount() > 0) + { + WarningPrinter threetenWarningPrinter = + new WarningPrinter(err, configuration.warn); + + ClassPool modifiedClasses = new ClassPool(); + ClassVisitor modifiedClassCollector = + new ClassPoolFiller(modifiedClasses); + + programClassPool.classesAccept( + // Do not process classes of the threeten library itself. + new ClassNameFilter("!org/threeten/bp/**", + new JSR310Converter(programClassPool, + libraryClassPool, + threetenWarningPrinter, + modifiedClassCollector, + replacedTimeMethodCallCounter))); + + // Re-Initialize references in modified classes. + modifiedClasses.classesAccept( + new ClassReferenceInitializer(programClassPool, + libraryClassPool)); + + int conversionWarningCount = threetenWarningPrinter.getWarningCount(); + if (conversionWarningCount > 0) + { + err.println("Warning: there were " + conversionWarningCount + + " Java 8 time API method calls that could not be backported."); + err.println(" You should check if a your project setup is correct (compileSdkVersion, threetenbp dependency)."); + err.println(" For more information, consult the section \'Integration->Gradle Plugin->Java 8 time API support\' in our manual"); + } + } + } + if (targetClassVersion != 0) { // Set the class version of all classes in the program ClassPool @@ -226,6 +325,8 @@ System.out.println(" Number of converted static interface methods: " + staticInterfaceMethodCounter.getCount()); System.out.println(" Number of converted default interface methods: " + defaultInterfaceMethodCounter.getCount()); System.out.println(" Number of replaced Java 7+ method calls: " + replacedMethodCallCounter.getCount()); + System.out.println(" Number of replaced Java 8 stream method calls: " + replacedStreamsMethodCallCounter.getCount()); + System.out.println(" Number of replaced Java 8 time method calls: " + replacedTimeMethodCallCounter.getCount()); } } } diff -Nru proguard-6.0.3/core/src/proguard/backport/DefaultInterfaceMethodConverter.java proguard-6.2.0/core/src/proguard/backport/DefaultInterfaceMethodConverter.java --- proguard-6.0.3/core/src/proguard/backport/DefaultInterfaceMethodConverter.java 2018-01-28 00:14:39.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/DefaultInterfaceMethodConverter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -30,10 +30,11 @@ import proguard.classfile.instruction.visitor.*; import proguard.classfile.util.*; import proguard.classfile.visitor.*; -import proguard.optimize.peephole.*; import proguard.util.StringTransformer; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; + /** * This ClassVisitor moves all default interface methods in the visited @@ -42,11 +43,11 @@ * @author Thomas Neidhart */ public class DefaultInterfaceMethodConverter -extends SimplifiedVisitor -implements ClassVisitor, +extends SimplifiedVisitor +implements ClassVisitor, - // Implementation interfaces. - AttributeVisitor + // Implementation interfaces. + AttributeVisitor { private final ClassVisitor modifiedClassVisitor; private final MemberVisitor extraMemberVisitor; @@ -67,9 +68,11 @@ // Implementations for ClassVisitor. + @Override public void visitLibraryClass(LibraryClass libraryClass) {} + @Override public void visitProgramClass(ProgramClass programClass) { hasDefaultMethods = false; @@ -78,7 +81,9 @@ // Collect all implementations of the interface. programClass.hierarchyAccept(false, false, false, true, new ProgramClassFilter( - new ClassCollector(implClasses))); + // Ignore other interfaces that extend this one. + new ClassAccessFilter(0, ClassConstants.ACC_INTERFACE, + new ClassCollector(implClasses)))); programClass.accept( new AllMethodVisitor( @@ -95,9 +100,11 @@ // Implementations for AttributeVisitor. + @Override public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + @Override public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { hasDefaultMethods = true; @@ -176,17 +183,27 @@ Clazz interfaceClass, Method defaultMethod) { - ConstantCounter counter = new ConstantCounter(); + final AtomicBoolean foundInvocation = new AtomicBoolean(false); clazz.accept( new AllMethodVisitor( new AllAttributeVisitor( new AllInstructionVisitor( - new InvocationInstructionMatcher(interfaceClass, - defaultMethod, - counter))))); + new SuperInvocationInstructionMatcher(interfaceClass, + defaultMethod) + { + @Override + public void superInvocation(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + CodeAttributeEditor codeAttributeEditor) + { + foundInvocation.set(true); + } + })))); - return counter.getCount() > 0; + return foundInvocation.get(); } @@ -218,70 +235,96 @@ String descriptor = interfaceMethod.getDescriptor(interfaceClass); Method targetMethod = targetClass.findMethod(targetMethodName, descriptor); - InstructionSequenceBuilder ____ = - new InstructionSequenceBuilder(); - - Instruction[] patternInstructions = - ____.invokespecial_interface(interfaceClass, - interfaceMethod).__(); - - Instruction[] replacementInstructions = - ____.invokevirtual(targetClass, - targetMethod).__(); - - CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); - - Constant[] constants = ____.constants(); + ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(targetClass); + final int constantIndex = constantPoolEditor.addMethodrefConstant(targetClass, targetMethod); targetClass.accept( new AllMethodVisitor( new AllAttributeVisitor( - new PeepholeOptimizer(null, codeAttributeEditor, - new InstructionSequenceReplacer(constants, - patternInstructions, - constants, - replacementInstructions, - null, - codeAttributeEditor))))); + new SuperInvocationInstructionMatcher(interfaceClass, + interfaceMethod) + { + @Override + public void superInvocation(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + CodeAttributeEditor codeAttributeEditor) + { + Instruction instruction = + new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, + constantIndex); + + codeAttributeEditor.replaceInstruction(offset, instruction); + } + }))); } /** - * This InstructionVisitor will call the specified ConstantVisitor + * This InstructionVisitor will call the {@code superInvocation(...)} method * for any encountered INVOKESPECIAL instruction whose associated * constant is an InterfaceMethodRefConstant and matches the given * referenced class and method. */ - private static class InvocationInstructionMatcher - extends SimplifiedVisitor - implements InstructionVisitor, - ConstantVisitor + private static class SuperInvocationInstructionMatcher + extends SimplifiedVisitor + implements AttributeVisitor, + InstructionVisitor, + ConstantVisitor { - private final Clazz referencedClass; - private final Method referencedMethod; - private final ConstantVisitor constantVisitor; - - public InvocationInstructionMatcher(Clazz referencedClass, - Method referencedMethod, - ConstantVisitor constantVisitor) + private final Clazz referencedClass; + private final Method referencedMethod; + private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); + + private boolean matchingInvocation; + + + public SuperInvocationInstructionMatcher(Clazz referencedClass, + Method referencedMethod) { this.referencedClass = referencedClass; this.referencedMethod = referencedMethod; - this.constantVisitor = constantVisitor; + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + // Set up the code attribute editor. + codeAttributeEditor.reset(codeAttribute.u4codeLength); + + // Find the peephole optimizations. + codeAttribute.instructionsAccept(clazz, method, this); + + // Apply the peephole optimizations. + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); } // Implementations for InstructionVisitor. + @Override public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + @Override public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) { switch (constantInstruction.opcode) { case InstructionConstants.OP_INVOKESPECIAL: + matchingInvocation = false; clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + + if (matchingInvocation) + { + superInvocation(clazz, method, codeAttribute, offset, codeAttributeEditor); + } break; } } @@ -289,16 +332,31 @@ // Implementations for ConstantVisitor. + @Override public void visitAnyConstant(Clazz clazz, Constant constant) {} + @Override public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) { if (interfaceMethodrefConstant.referencedClass == referencedClass && interfaceMethodrefConstant.referencedMember == referencedMethod) { - constantVisitor.visitInterfaceMethodrefConstant(clazz, interfaceMethodrefConstant); + matchingInvocation = true; } } + + + /** + * The callback method which will be called for each detected super invocation + * of the specified interface method. + */ + public void superInvocation(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + CodeAttributeEditor codeAttributeEditor) {} } } + + diff -Nru proguard-6.0.3/core/src/proguard/backport/JSR310Converter.java proguard-6.2.0/core/src/proguard/backport/JSR310Converter.java --- proguard-6.0.3/core/src/proguard/backport/JSR310Converter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/JSR310Converter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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; + +import proguard.classfile.ClassPool; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.WarningPrinter; +import proguard.classfile.visitor.ClassVisitor; + +/** + * This ClassVisitor will replace any occurrence of java.time.** related methods / types + * that have been introduced in Java 8 to the threetenbp library. + * + * @author Thomas Neidhart + */ +public class JSR310Converter +extends AbstractAPIConverter +{ + /** + * Create a new JSR310Converter instance. + */ + public JSR310Converter(ClassPool programClassPool, + ClassPool libraryClassPool, + WarningPrinter warningPrinter, + ClassVisitor modifiedClassVisitor, + InstructionVisitor extraInstructionVisitor) + { + super(programClassPool, + libraryClassPool, + warningPrinter, + modifiedClassVisitor, + extraInstructionVisitor); + + TypeReplacement[] typeReplacements = new TypeReplacement[] + { + // java.time package has been added in Java 8 + replace("java/time/**", "org/threeten/bp/<1>"), + }; + + MethodReplacement[] methodReplacements = new MethodReplacement[] + { + // all classes in java.time.** are converted to + // org.threeeten.bp.**. + replace("java/time/**", "**", "**", + "org/threeten/bp/<1>", "<1>", "<1>"), + }; + + setTypeReplacements(typeReplacements); + setMethodReplacements(methodReplacements); + } +} diff -Nru proguard-6.0.3/core/src/proguard/backport/LambdaExpressionCollector.java proguard-6.2.0/core/src/proguard/backport/LambdaExpressionCollector.java --- proguard-6.0.3/core/src/proguard/backport/LambdaExpressionCollector.java 2018-05-03 10:51:05.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/LambdaExpressionCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -62,9 +62,11 @@ // Implementations for ClassVisitor. + @Override public void visitLibraryClass(LibraryClass libraryClass) {} + @Override public void visitProgramClass(ProgramClass programClass) { // Visit any InvokeDynamic constant. @@ -76,9 +78,11 @@ // Implementations for ConstantVisitor. + @Override public void visitAnyConstant(Clazz clazz, Constant constant) {} + @Override public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { referencedInvokeDynamicConstant = invokeDynamicConstant; @@ -87,6 +91,7 @@ } + @Override public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant) { referencedInvokedClass = refConstant.referencedClass; @@ -96,9 +101,11 @@ // Implementations for AttributeVisitor. + @Override public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + @Override public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) { @@ -108,6 +115,7 @@ // Implementations for BootstrapMethodInfoVisitor. + @Override public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) { ProgramClass programClass = (ProgramClass) clazz; @@ -233,4 +241,4 @@ { return (MethodTypeConstant) programClass.getConstant(constantIndex); } -} +} \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/backport/LambdaExpressionConverter.java proguard-6.2.0/core/src/proguard/backport/LambdaExpressionConverter.java --- proguard-6.0.3/core/src/proguard/backport/LambdaExpressionConverter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/LambdaExpressionConverter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -29,7 +29,7 @@ import proguard.classfile.instruction.visitor.*; import proguard.classfile.util.*; import proguard.classfile.visitor.*; -import proguard.util.*; +import proguard.util.MultiValueMap; import java.util.*; @@ -177,8 +177,8 @@ if (lambdaExpression.isStateless()) { builder.getstatic(lambdaClassName, - LAMBDA_SINGLETON_FIELD_NAME, - ClassUtil.internalTypeFromClassName(lambdaClassName)); + LAMBDA_SINGLETON_FIELD_NAME, + ClassUtil.internalTypeFromClassName(lambdaClassName)); } else { @@ -199,11 +199,11 @@ // and it is a Category 1 value, we can avoid storing the // current stack to variables. builder.new_(lambdaClassName) - .dup_x1() - .swap() - .invokespecial(lambdaClassName, - ClassConstants.METHOD_NAME_INIT, - methodDescriptor); + .dup_x1() + .swap() + .invokespecial(lambdaClassName, + ClassConstants.METHOD_NAME_INIT, + methodDescriptor); } else { @@ -251,8 +251,8 @@ } builder.invokespecial(lambdaClassName, - ClassConstants.METHOD_NAME_INIT, - methodDescriptor); + ClassConstants.METHOD_NAME_INIT, + methodDescriptor); } } @@ -265,8 +265,11 @@ // Implementations for MemberVisitor. + @Override public void visitAnyMember(Clazz clazz, Member member) {} + + @Override public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { if (isDeserializationHook(programClass, programMethod)) @@ -328,14 +331,22 @@ // data structure for later use. lambdaExpression.lambdaClass = lambdaClass; - // Apply some optimizations to the lambda expression to - // avoid creating accessor methods all the time. - //fixAccessFlags(lambdaExpression); - - // In case the invoked method can not be accessed directly - // by the lambda class, add a synthetic accessor method. - if (lambdaExpression.needsAccessorMethod()) + // [DGD-968] When a lambda expression is called from a `default` + // interface method, ensure that it is stateless and visible to the + // lambda class instead of generating an accessor method. The method + // will be properly backported by the {@link StaticInterfaceMethodConverter}. + if (lambdaExpression.referencesPrivateSyntheticInterfaceMethod()) + { + fixInterfaceLambdaMethod(lambdaExpression.referencedClass, + (ProgramMethod) lambdaExpression.referencedInvokedMethod, + lambdaExpression); + } + else if (lambdaExpression.referencesPrivateConstructor() || + lambdaExpression.needsAccessorMethod()) { + // In case the invoked method can not be accessed directly + // by the lambda class, add a synthetic accessor method. + addAccessorMethod(lambdaExpression.referencedClass, lambdaExpression); } @@ -358,31 +369,31 @@ } - private void fixAccessFlags(LambdaExpression lambdaExpression) + private void fixInterfaceLambdaMethod(ProgramClass programClass, + ProgramMethod programMethod, + LambdaExpression lambdaExpression) { - // If the invoked method is private, we can make it package-private - // to be able to access it from the lambda class. Otherwise we would - // need to add an additional accessor method. - if (lambdaExpression.referencedInvokedMethod instanceof ProgramMethod) - { - ProgramMethod invokedProgramMethod = - (ProgramMethod) lambdaExpression.referencedInvokedMethod; - - int currentAccessFlags = invokedProgramMethod.getAccessFlags(); - if ((currentAccessFlags & ClassConstants.ACC_PRIVATE) != 0) - { - invokedProgramMethod.u2accessFlags = - AccessUtil.replaceAccessFlags(currentAccessFlags, - AccessUtil.accessFlags(AccessUtil.PACKAGE_VISIBLE)); - - // In case of instance-capturing lambdas or method references to private - // methods the reference kind is invokeSpecial. After fixing the - // access flags we need to update the reference kind as well. - if (lambdaExpression.invokedReferenceKind == ClassConstants.REF_invokeSpecial) - { - lambdaExpression.invokedReferenceKind = ClassConstants.REF_invokeVirtual; - } - } + // Change the access flags to package private to make the method + // accessible from the lambda class. + programMethod.accept(programClass, new MemberAccessSetter(0)); + + // If the method is not yet static, make it static + // by updating its access flags / descriptor. + if ((programMethod.getAccessFlags() & (ClassConstants.ACC_STATIC)) == 0) + { + programMethod.accept(programClass, + new MemberAccessFlagSetter(ClassConstants.ACC_STATIC)); + + String newDescriptor = + prependParameterToMethodDescriptor(lambdaExpression.invokedMethodDesc, + ClassUtil.internalTypeFromClassType(programClass.getName())); + + programMethod.u2descriptorIndex = + (new ConstantPoolEditor(programClass).addUtf8Constant(newDescriptor)); + + // Update the lambda expression accordingly. + lambdaExpression.invokedMethodDesc = newDescriptor; + lambdaExpression.invokedReferenceKind = ClassConstants.REF_invokeStatic; } } @@ -409,7 +420,31 @@ int accessFlags = lambdaExpression.referencedInvokedMethod.getAccessFlags(); - if ((accessFlags & ClassConstants.ACC_STATIC) == 0) + // Method reference to a constructor. + if (lambdaExpression.invokedReferenceKind == ClassConstants.REF_newInvokeSpecial) + { + // Replace the return type of the accessor method -> change to created type. + + // Collect first all parameters. + List invokedParameterTypes = new ArrayList(); + int methodParameterSize = + ClassUtil.internalMethodParameterSize(accessorMethodDescriptor); + for (int i = 0; i < methodParameterSize; i++) + { + String invokedParameterType = + ClassUtil.internalMethodParameterType(accessorMethodDescriptor, i); + invokedParameterTypes.add(invokedParameterType); + } + + String invokedClassType = + ClassUtil.internalTypeFromClassName(lambdaExpression.invokedClassName); + + // Build new method descriptor with the updated return type. + accessorMethodDescriptor = + ClassUtil.internalMethodDescriptorFromInternalTypes(invokedClassType, + invokedParameterTypes); + } + else if ((accessFlags & ClassConstants.ACC_STATIC) == 0) { accessorMethodDescriptor = prependParameterToMethodDescriptor(accessorMethodDescriptor, @@ -423,7 +458,15 @@ accessorMethodDescriptor, 50); - // Load the parameters first. + // If the lambda expression is a method reference to a constructor, + // we need to create the object first. + if (lambdaExpression.invokedReferenceKind == ClassConstants.REF_newInvokeSpecial) + { + composer.new_(lambdaExpression.invokedClassName) + .dup(); + } + + // Load the parameters next. InternalTypeEnumeration typeEnumeration = new InternalTypeEnumeration(accessorMethodDescriptor); @@ -988,4 +1031,4 @@ composer.checkcast(ClassUtil.internalClassTypeFromType(targetType)); } } -} +} \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/backport/LambdaExpression.java proguard-6.2.0/core/src/proguard/backport/LambdaExpression.java --- proguard-6.0.3/core/src/proguard/backport/LambdaExpression.java 2018-05-06 20:31:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/LambdaExpression.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -20,13 +20,9 @@ */ package proguard.backport; -import proguard.classfile.ClassConstants; -import proguard.classfile.Clazz; -import proguard.classfile.Method; -import proguard.classfile.ProgramClass; +import proguard.classfile.*; import proguard.classfile.attribute.BootstrapMethodInfo; -import proguard.classfile.util.ClassUtil; -import proguard.classfile.util.MemberFinder; +import proguard.classfile.util.*; /** * A small helper class that captures useful information @@ -63,7 +59,7 @@ public String invokedMethodName; public String invokedMethodDesc; - public Clazz referencedInvokedClass; + public Clazz referencedInvokedClass; public Method referencedInvokedMethod; // The created lambda class. @@ -181,6 +177,18 @@ /** + * Returns whether the invoked method is a non-static, private synthetic + * method in an interface. + */ + boolean referencesPrivateSyntheticInterfaceMethod() + { + return (referencedInvokedClass .getAccessFlags() & ClassConstants.ACC_INTERFACE) != 0 && + (referencedInvokedMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE | + ClassConstants.ACC_SYNTHETIC)) != 0 ; + } + + + /** * Returns whether an accessor method is needed to access * the invoked method from the lambda class. */ @@ -195,6 +203,18 @@ } + /** + * Returns whether the lambda expression is a method reference + * to a private constructor. + */ + public boolean referencesPrivateConstructor() + { + return invokedReferenceKind == ClassConstants.REF_newInvokeSpecial && + ClassConstants.METHOD_NAME_INIT.equals(invokedMethodName) && + (referencedInvokedMethod.getAccessFlags() & ClassConstants.ACC_PRIVATE) != 0; + } + + // Small Utility methods. private static final String LAMBDA_METHOD_PREFIX = "lambda$"; @@ -204,3 +224,5 @@ return methodName.startsWith(LAMBDA_METHOD_PREFIX); } } + + diff -Nru proguard-6.0.3/core/src/proguard/backport/StaticInterfaceMethodConverter.java proguard-6.2.0/core/src/proguard/backport/StaticInterfaceMethodConverter.java --- proguard-6.0.3/core/src/proguard/backport/StaticInterfaceMethodConverter.java 2018-01-28 00:14:39.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/StaticInterfaceMethodConverter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -21,25 +21,18 @@ package proguard.backport; import proguard.classfile.*; -import proguard.classfile.attribute.visitor.AllAttributeVisitor; -import proguard.classfile.attribute.visitor.AttributeToClassVisitor; -import proguard.classfile.attribute.visitor.InstructionToAttributeVisitor; -import proguard.classfile.constant.Constant; -import proguard.classfile.constant.RefConstant; -import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.*; import proguard.classfile.editor.*; import proguard.classfile.instruction.Instruction; -import proguard.classfile.instruction.visitor.InstructionVisitor; -import proguard.classfile.util.ClassReferenceInitializer; -import proguard.classfile.util.ClassSuperHierarchyInitializer; -import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.instruction.visitor.*; +import proguard.classfile.util.*; import proguard.classfile.visitor.*; -import proguard.optimize.peephole.InstructionSequencesReplacer; -import proguard.optimize.peephole.PeepholeOptimizer; +import proguard.optimize.peephole.*; import proguard.util.MultiValueMap; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * This ClassVisitor moves all static interface methods in the visited @@ -59,11 +52,11 @@ private final MemberVisitor extraMemberVisitor; - public StaticInterfaceMethodConverter(ClassPool programClassPool, - ClassPool libraryClassPool, - MultiValueMap injectedClassNameMap, - ClassVisitor modifiedClassVisitor, - MemberVisitor extraMemberVisitor) + public StaticInterfaceMethodConverter(ClassPool programClassPool, + ClassPool libraryClassPool, + MultiValueMap injectedClassNameMap, + ClassVisitor modifiedClassVisitor, + MemberVisitor extraMemberVisitor) { this.programClassPool = programClassPool; this.libraryClassPool = libraryClassPool; @@ -75,9 +68,11 @@ // Implementations for ClassVisitor. + @Override public void visitLibraryClass(LibraryClass libraryClass) {} + @Override public void visitProgramClass(ProgramClass programClass) { // Collect all static methods of the interface class. @@ -117,7 +112,7 @@ // interface class. memberRemover ) - )))); + )))); // Add the utility class to the program class pool // and the injected class name map. @@ -155,7 +150,7 @@ new ProgramClass(ClassConstants.CLASS_VERSION_1_2, 1, new Constant[10], - 0, + ClassConstants.ACC_PUBLIC | ClassConstants.ACC_SYNTHETIC, 0, 0); @@ -175,9 +170,9 @@ // Add a private constructor. classEditor.addMethod(ClassConstants.ACC_PRIVATE, - ClassConstants.METHOD_NAME_INIT, - ClassConstants.METHOD_TYPE_INIT, - 10) + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT, + 10) .aload_0() .invokespecial(ClassConstants.NAME_JAVA_LANG_OBJECT, ClassConstants.METHOD_NAME_INIT, @@ -251,16 +246,16 @@ * reference a given class via any RefConstant. */ private static class MyReferencedClassFilter - extends SimplifiedVisitor + extends SimplifiedVisitor implements ClassVisitor, - ConstantVisitor + ConstantVisitor { - private final Clazz referencedClass; + private final Clazz referencedClass; private final ClassVisitor classVisitor; private boolean referenceClassFound; - public MyReferencedClassFilter(Clazz referencedClass, + public MyReferencedClassFilter(Clazz referencedClass, ClassVisitor classVisitor) { this.referencedClass = referencedClass; diff -Nru proguard-6.0.3/core/src/proguard/backport/StreamSupportConverter.java proguard-6.2.0/core/src/proguard/backport/StreamSupportConverter.java --- proguard-6.0.3/core/src/proguard/backport/StreamSupportConverter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/StreamSupportConverter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,321 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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; + +import proguard.classfile.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; + +/** + * This ClassVisitor will replace any occurrence of stream related methods / types + * that have been introduced in Java 8 to the streamsupport library. + * + * @author Thomas Neidhart + */ +public class StreamSupportConverter +extends AbstractAPIConverter +{ + /** + * Create a new StreamSupportConverter instance. + */ + public StreamSupportConverter(ClassPool programClassPool, + ClassPool libraryClassPool, + WarningPrinter warningPrinter, + ClassVisitor modifiedClassVisitor, + InstructionVisitor extraInstructionVisitor) + { + super(programClassPool, + libraryClassPool, + warningPrinter, + modifiedClassVisitor, + extraInstructionVisitor); + + TypeReplacement[] typeReplacements = new TypeReplacement[] + { + // j.u.stream package has been added in Java 8 + replace("java/util/stream/**", "java8/util/stream/<1>"), + + // j.u.function package has been added in Java 8 + replace("java/util/function/**", "java8/util/function/<1>"), + + // j.u classes / interfaces that have been added in Java 8 + replace("java/util/DoubleSummaryStatistics", "java8/util/DoubleSummaryStatistics"), + replace("java/util/IntSummaryStatistics", "java8/util/IntSummaryStatistics"), + replace("java/util/LongSummaryStatistics", "java8/util/LongSummaryStatistics"), + replace("java/util/PrimitiveIterator**", "java8/util/PrimitiveIterator<1>"), + replace("java/util/Optional**", "java8/util/Optional<1>"), + replace("java/util/Spliterator**", "java8/util/Spliterator<1>"), + replace("java/util/SplittableRandom", "java8/util/SplittableRandom"), + replace("java/util/StringJoiner", "java8/util/StringJoiner"), + + // j.u.c classes / exceptions that have been added in Java 8 or being updated in Java 8 + replace("java/util/concurrent/CompletionException", "java8/util/concurrent/CompletionException"), + replace("java/util/concurrent/CountedCompleter", "java8/util/concurrent/CountedCompleter"), + replace("java/util/concurrent/ForkJoinPool", "java8/util/concurrent/ForkJoinPool"), + replace("java/util/concurrent/ForkJoinTask", "java8/util/concurrent/ForkJoinTask"), + replace("java/util/concurrent/ForkJoinWorkerTask", "java8/util/concurrent/ForkJoinWorkerTask"), + replace("java/util/concurrent/Phaser", "java8/util/concurrent/Phaser"), + replace("java/util/concurrent/RecursiveAction", "java8/util/concurrent/RecursiveAction"), + replace("java/util/concurrent/RecursiveTask", "java8/util/concurrent/RecursiveTask"), + replace("java/util/concurrent/ThreadLocalRandom", "java8/util/concurrent/ThreadLocalRandom"), + + // j.l classes / annotations that have been added in Java 8 + replace("java/lang/FunctionalInterface", "java8/lang/FunctionalInterface"), + }; + + MethodReplacement[] methodReplacements = new MethodReplacement[] + { + // default methods in j.u.Collection + replace("java/util/Collection", "stream", "()Ljava/util/stream/Stream;", + "java8/util/stream/StreamSupport", "stream", "(Ljava/util/Collection;)Ljava8/util/stream/Stream;"), + replace("java/util/Collection", "parallelStream", "()Ljava/util/stream/Stream;", + "java8/util/stream/StreamSupport", "parallelStream", "(Ljava/util/Collection;)Ljava8/util/stream/Stream;"), + replace("java/util/Collection", "spliterator", "()Ljava/util/Spliterator;", + "java8/util/Spliterators", "spliterator", "(Ljava/util/Collection;)Ljava8/util/Spliterator;"), + replace("java/util/Collection", "removeIf", "(Ljava/util/function/Predicate;)Z", + "java8/lang/Iterables", "removeIf", "(Ljava/lang/Iterable;Ljava8/util/function/Predicate;)Z"), + + // default methods in j.l.Iterable + replace("java/lang/Iterable", "forEach", "(Ljava/util/function/Consumer;)V", + "java8/lang/Iterables", "forEach", "(Ljava/lang/Iterable;Ljava8/util/function/Consumer;)V"), + replace("java/lang/Iterable", "spliterator", "()Ljava/util/stream/Stream;", + "java8/lang/Iterables", "spliterator", "(Ljava/lang/Iterable;)Ljava8/util/stream/Stream;"), + + // remaining default methods in j.u.List + replace("java/util/List", "", "**", + "java8/util/Lists", "<1>", "<1>"), + + // default methods in j.u.Map + replace("java/util/Map", "", "**", + "java8/util/Maps", "<1>", "<1>"), + + // static methods in j.u.Map$Entry + replace("java/util/Map$Entry", "", "**", + "java8/util/Maps", "<1>", "<1>"), + + // default and static methods in j.u.Comparator + replace("java/util/Comparator", "", "**", + "java8/util/Comparators", "<1>", "<1>"), + replace("java/util/Comparator", "", "**", + "java8/util/Comparators", "<1>", "<1>"), + + // all methods of new classes in j.u. + replace("java/util/DoubleSummaryStatistics", "**", "**", + "java8/util/DoubleSummaryStatistics", "<1>", "<1>"), + replace("java/util/IntSummaryStatistics", "**", "**", + "java8/util/IntSummaryStatistics", "<1>", "<1>"), + replace("java/util/LongSummaryStatistics", "**", "**", + "java8/util/LongSummaryStatistics", "<1>", "<1>"), + replace("java/util/PrimitiveIterator**", "**", "**", + "java8/util/PrimitiveIterator<1>", "<1>", "<1>"), + replace("java/util/Optional**", "**", "**", + "java8/util/Optional<1>", "<1>", "<1>"), + replace("java/util/Spliterator**", "**", "**", + "java8/util/Spliterator<1>", "<1>", "<1>"), + replace("java/util/SplittableRandom", "**", "**", + "java8/util/SplittableRandom", "<1>", "<1>"), + replace("java/util/StringJoiner", "**", "**", + "java8/util/StringJoiner", "<1>", "<1>"), + + // default and static methods in new interfaces. + replace("java/util/function/BiConsumer", "", "**", + "java8/util/function/BiConsumers", "<1>", "<1>"), + replace("java/util/function/BiFunction", "", "**", + "java8/util/function/BiFunctions", "<1>", "<1>"), + replace("java/util/function/BinaryOperator", "", "**", + "java8/util/function/BinaryOperators", "<1>", "<1>"), + replace("java/util/function/BiPredicate", "", "**", + "java8/util/function/BiPredicates", "<1>", "<1>"), + replace("java/util/function/Consumer", "", "**", + "java8/util/function/Consumers", "<1>", "<1>"), + replace("java/util/function/DoubleConsumer", "", "**", + "java8/util/function/DoubleConsumers", "<1>", "<1>"), + replace("java/util/function/DoublePredicate", "", "**", + "java8/util/function/DoublePredicates", "<1>", "<1>"), + + replace("java/util/function/DoubleUnaryOperator", "", "**", + "java8/util/function/DoubleUnaryOperators", "<1>", "<1>"), + replace("java/util/function/DoubleUnaryOperator", "", "**", + "java8/util/function/DoubleUnaryOperators", "<1>", "<1>"), + + replace("java/util/function/Function", "", "**", + "java8/util/function/Functions", "<1>", "<1>"), + replace("java/util/function/Function", "", "**", + "java8/util/function/Functions", "<1>", "<1>"), + + replace("java/util/function/IntConsumer", "", "**", + "java8/util/function/IntConsumers", "<1>", "<1>"), + replace("java/util/function/IntPredicate", "", "**", + "java8/util/function/IntPredicates", "<1>", "<1>"), + + replace("java/util/function/IntUnaryOperator", "", "**", + "java8/util/function/IntUnaryOperators", "<1>", "<1>"), + replace("java/util/function/IntUnaryOperator", "", "**", + "java8/util/function/IntUnaryOperators", "<1>", "<1>"), + + replace("java/util/function/LongConsumer", "", "**", + "java8/util/function/LongConsumers", "<1>", "<1>"), + replace("java/util/function/LongPredicate", "", "**", + "java8/util/function/LongPredicates", "<1>", "<1>"), + + replace("java/util/function/LongUnaryOperator", "", "**", + "java8/util/function/LongUnaryOperators", "<1>", "<1>"), + replace("java/util/function/LongUnaryOperator", "", "**", + "java8/util/function/LongUnaryOperators", "<1>", "<1>"), + + replace("java/util/function/Predicate", "", "**", + "java8/util/function/Predicates", "<1>", "<1>"), + replace("java/util/function/Predicate", "", "**", + "java8/util/function/Predicates", "<1>", "<1>"), + + replace("java/util/function/UnaryOperator", "", "**", + "java8/util/function/UnaryOperators", "<1>", "<1>"), + + // static methods in new interfaces. + replace("java/util/stream/DoubleStream", "", "**", + "java8/util/stream/DoubleStreams", "<1>", "<1>"), + replace("java/util/stream/IntStream", "", "**", + "java8/util/stream/IntStreams", "<1>", "<1>"), + replace("java/util/stream/LongStream", "", "**", + "java8/util/stream/LongStreams", "<1>", "<1>"), + replace("java/util/stream/Stream", "", "**", + "java8/util/stream/RefStreams", "<1>", "<1>"), + + replace("java/util/stream/Collector", "", "**", + "java8/util/stream/Collectors", "<1>", "<1>"), + + // remaining methods in new classes. + replace("java/util/stream/**", "**", "**", + "java8/util/stream/<1>", "<1>", "<1>"), + replace("java/util/function/**", "**", "**", + "java8/util/function/<1>", "<1>", "<1>"), + + // default methods in Iterator. + replace("java/util/Iterator", "forEachRemaining", "(Ljava/util/function/Consumer;)V", + "java8/util/Iterators", "forEachRemaining", "(Ljava/lang/Iterable;Ljava8/util/function/Consumer;)V"), + + // new methods in j.u.c. + replace("java/util/concurrent/ConcurrentMap", "", "**", + "java8/util/concurrent/ConcurrentMaps", "<1>", "<1>"), + + replace("java/util/concurrent/CompletionException", "**", "**", + "java8/util/concurrent/CompletionException", "<1>", "<1>"), + replace("java/util/concurrent/CountedCompleter", "**", "**", + "java8/util/concurrent/CountedCompleter", "<1>", "<1>"), + replace("java/util/concurrent/ForkJoinPool", "**", "**", + "java8/util/concurrent/ForkJoinPool", "<1>", "<1>"), + replace("java/util/concurrent/ForkJoinTask", "**", "**", + "java8/util/concurrent/ForkJoinTask", "<1>", "<1>"), + replace("java/util/concurrent/ForkJoinWorkerTask", "**", "**", + "java8/util/concurrent/ForkJoinWorkerTask", "<1>", "<1>"), + replace("java/util/concurrent/Phaser", "**", "**", + "java8/util/concurrent/Phaser", "<1>", "<1>"), + replace("java/util/concurrent/RecursiveAction", "**", "**", + "java8/util/concurrent/RecursiveAction", "<1>", "<1>"), + replace("java/util/concurrent/RecursiveTask", "**", "**", + "java8/util/concurrent/RecursiveTask", "<1>", "<1>"), + replace("java/util/concurrent/ForkJoinPool", "**", "**", + "java8/util/concurrent/ForkJoinPool", "<1>", "<1>"), + + // static methods + replace("java/util/concurrent/ThreadLocalRandom", "ints", "**", + "java8/util/concurrent/ThreadLocalRandom", "ints", "<1>"), + replace("java/util/concurrent/ThreadLocalRandom", "longs", "**", + "java8/util/concurrent/ThreadLocalRandom", "longs", "<1>"), + replace("java/util/concurrent/ThreadLocalRandom", "doubles", "**", + "java8/util/concurrent/ThreadLocalRandom", "doubles", "<1>"), + // remaining + replace("java/util/concurrent/ThreadLocalRandom", "**", "**", + "java8/util/concurrent/ThreadLocalRandom", "<1>", "<1>"), + + // new methods in j.u.Arrays. + replace("java/util/Arrays", "spliterator", "**", + "java8/util/J8Arrays", "spliterator", "<1>"), + replace("java/util/Arrays", "stream", "**", + "java8/util/J8Arrays", "stream", "<1>"), + replace("java/util/Arrays", "parallel**", "**", + "java8/util/J8Arrays", "<1>", "<1>"), + replace("java/util/Arrays", "set**", "**", + "java8/util/J8Arrays", "<1>", "<1>"), + + // new methods in j.l.Integer. + replace("java/lang/Integer", "min", "**", + "java8/lang/Integers", "min", "<1>"), + replace("java/lang/Integer", "max", "**", + "java8/lang/Integers", "max", "<1>"), + replace("java/lang/Integer", "sum", "**", + "java8/lang/Integers", "sum", "<1>"), + replace("java/lang/Integer", "compare", "**", + "java8/lang/Integers", "compare", "<1>"), + replace("java/lang/Integer", "compareUnsigned", "**", + "java8/lang/Integers", "compareUnsigned", "<1>"), + replace("java/lang/Integer", "remainderUnsigned", "**", + "java8/lang/Integers", "remainderUnsigned", "<1>"), + replace("java/lang/Integer", "divideUnsigned", "**", + "java8/lang/Integers", "divideUnsigned", "<1>"), + replace("java/lang/Integer", "toUnsignedLong", "**", + "java8/lang/Integers", "toUnsignedLong", "<1>"), + replace("java/lang/Integer", "hashCode", "(I)I", + "java8/lang/Integers", "hashCode", "(I)I"), + + // new methods in j.l.Long. + replace("java/lang/Long", "min", "**", + "java8/lang/Longs", "min", "<1>"), + replace("java/lang/Long", "max", "**", + "java8/lang/Longs", "max", "<1>"), + replace("java/lang/Long", "sum", "**", + "java8/lang/Longs", "sum", "<1>"), + replace("java/lang/Long", "compare", "**", + "java8/lang/Longs", "compare", "<1>"), + replace("java/lang/Long", "compareUnsigned", "**", + "java8/lang/Longs", "compareUnsigned", "<1>"), + replace("java/lang/Long", "remainderUnsigned", "**", + "java8/lang/Longs", "remainderUnsigned", "<1>"), + replace("java/lang/Long", "divideUnsigned", "**", + "java8/lang/Longs", "divideUnsigned", "<1>"), + replace("java/lang/Long", "toUnsignedBigInteger", "**", + "java8/lang/Longs", "toUnsignedBigInteger", "<1>"), + replace("java/lang/Long", "hashCode", "(J)I", + "java8/lang/Longs", "hashCode", "(J)I"), + + // new methods in j.l.Double. + replace("java/lang/Double", "min", "**", + "java8/lang/Doubles", "min", "<1>"), + replace("java/lang/Double", "max", "**", + "java8/lang/Doubles", "max", "<1>"), + replace("java/lang/Double", "sum", "**", + "java8/lang/Doubles", "sum", "<1>"), + replace("java/lang/Double", "isFinite", "**", + "java8/lang/Doubles", "isFinite", "<1>"), + replace("java/lang/Double", "hashCode", "(D)I", + "java8/lang/Doubles", "hashCode", "(D)I"), + + // missing replacements for methods added to j.u.Random. + missing("java/util/Random", "ints", "**"), + missing("java/util/Random", "longs", "**"), + missing("java/util/Random", "doubles", "**") + }; + + setTypeReplacements(typeReplacements); + setMethodReplacements(methodReplacements); + } +} diff -Nru proguard-6.0.3/core/src/proguard/backport/StringConcatenationConverter.java proguard-6.2.0/core/src/proguard/backport/StringConcatenationConverter.java --- proguard-6.0.3/core/src/proguard/backport/StringConcatenationConverter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/backport/StringConcatenationConverter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -29,11 +29,12 @@ import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; import proguard.classfile.util.*; +import proguard.classfile.visitor.*; import java.util.*; /** - * This InstructionVistor converts all indy String Concatenations in the visited + * This InstructionVisitor converts all indy String Concatenations in the visited * classes to StringBuilder-append chains. * * @author Tim Van Den Broecke @@ -48,8 +49,8 @@ ConstantVisitor { // Constants as per specification - private static final char C_VARIABLE_ARGUMENT = '\u0001'; - private static final char C_CONSTANT_ARGUMENT = '\u0002'; + private static final char C_VARIABLE_ARGUMENT = '\u0001'; + private static final char C_CONSTANT_ARGUMENT = '\u0002'; private final InstructionVisitor extraInstructionVisitor; private final CodeAttributeEditor codeAttributeEditor; @@ -81,7 +82,7 @@ ProgramClass programClass = (ProgramClass) clazz; InvokeDynamicConstant invokeDynamicConstant = - (InvokeDynamicConstant) programClass.getConstant(constantInstruction.constantIndex); + (InvokeDynamicConstant) programClass.getConstant(constantInstruction.constantIndex); // Remember the referenced bootstrap method index and extract the recipe from it. referencedBootstrapMethodIndex = invokeDynamicConstant.getBootstrapMethodAttributeIndex(); @@ -121,7 +122,7 @@ // Loop over the recipe. // Push the local variables one by one, insert - // constants where necessary and create an append + // constants where necessary and create and append // instruction chain. typeIterator = types.listIterator(); for (int argIndex = 0, constantCounter = 0; argIndex < concatenationRecipe.length(); argIndex++) @@ -230,7 +231,6 @@ Arrays.copyOfRange(bootstrapMethodInfo.u2methodArguments, 1, bootstrapMethodInfo.u2methodArgumentCount) : new int[0]; } - } @@ -277,25 +277,29 @@ private static int typicalStringLengthFromType(String internalTypeName) { - return internalTypeName.equals(ClassConstants.TYPE_BOOLEAN) ? ClassConstants.MAXIMUM_BOOLEAN_AS_STRING_LENGTH : - internalTypeName.equals(ClassConstants.TYPE_CHAR) ? ClassConstants.MAXIMUM_CHAR_AS_STRING_LENGTH : - internalTypeName.equals(ClassConstants.TYPE_INT) ? ClassConstants.MAXIMUM_INT_AS_STRING_LENGTH : - internalTypeName.equals(ClassConstants.TYPE_LONG) ? ClassConstants.MAXIMUM_LONG_AS_STRING_LENGTH : - internalTypeName.equals(ClassConstants.TYPE_FLOAT) ? ClassConstants.MAXIMUM_FLOAT_AS_STRING_LENGTH : - internalTypeName.equals(ClassConstants.TYPE_DOUBLE) ? ClassConstants.MAXIMUM_DOUBLE_AS_STRING_LENGTH : - ClassConstants.DEFAULT_STRINGBUILDER_INIT_SIZE ; + return internalTypeName.equals(String.valueOf(ClassConstants.TYPE_BOOLEAN)) ? ClassConstants.MAXIMUM_BOOLEAN_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_CHAR)) ? ClassConstants.MAXIMUM_CHAR_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_BYTE)) ? ClassConstants.MAXIMUM_BYTE_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_SHORT)) ? ClassConstants.MAXIMUM_SHORT_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_INT)) ? ClassConstants.MAXIMUM_INT_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_LONG)) ? ClassConstants.MAXIMUM_LONG_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_FLOAT)) ? ClassConstants.MAXIMUM_FLOAT_AS_STRING_LENGTH : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_DOUBLE)) ? ClassConstants.MAXIMUM_DOUBLE_AS_STRING_LENGTH : + ClassConstants.DEFAULT_STRINGBUILDER_INIT_SIZE ; } private static String appendDescriptorFromInternalType(String internalTypeName) { - return internalTypeName.equals(ClassConstants.TYPE_BOOLEAN) ? ClassConstants.METHOD_TYPE_BOOLEAN_STRING_BUILDER : - internalTypeName.equals(ClassConstants.TYPE_CHAR) ? ClassConstants.METHOD_TYPE_CHAR_STRING_BUILDER : - internalTypeName.equals(ClassConstants.TYPE_INT) ? ClassConstants.METHOD_TYPE_INT_STRING_BUILDER : - internalTypeName.equals(ClassConstants.TYPE_LONG) ? ClassConstants.METHOD_TYPE_LONG_STRING_BUILDER : - internalTypeName.equals(ClassConstants.TYPE_FLOAT) ? ClassConstants.METHOD_TYPE_FLOAT_STRING_BUILDER : - internalTypeName.equals(ClassConstants.TYPE_DOUBLE) ? ClassConstants.METHOD_TYPE_DOUBLE_STRING_BUILDER : - internalTypeName.equals(ClassConstants.TYPE_JAVA_LANG_STRING) ? ClassConstants.METHOD_TYPE_STRING_STRING_BUILDER : - ClassConstants.METHOD_TYPE_OBJECT_STRING_BUILDER ; + return internalTypeName.equals(String.valueOf(ClassConstants.TYPE_BOOLEAN)) ? ClassConstants.METHOD_TYPE_BOOLEAN_STRING_BUILDER : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_CHAR)) ? ClassConstants.METHOD_TYPE_CHAR_STRING_BUILDER : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_BYTE)) || + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_SHORT)) || + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_INT)) ? ClassConstants.METHOD_TYPE_INT_STRING_BUILDER : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_LONG)) ? ClassConstants.METHOD_TYPE_LONG_STRING_BUILDER : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_FLOAT)) ? ClassConstants.METHOD_TYPE_FLOAT_STRING_BUILDER : + internalTypeName.equals(String.valueOf(ClassConstants.TYPE_DOUBLE)) ? ClassConstants.METHOD_TYPE_DOUBLE_STRING_BUILDER : + internalTypeName.equals(ClassConstants.TYPE_JAVA_LANG_STRING) ? ClassConstants.METHOD_TYPE_STRING_STRING_BUILDER : + ClassConstants.METHOD_TYPE_OBJECT_STRING_BUILDER ; } private static int nextArgIndex(String recipe, int fromIndex) diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/Annotation.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/Annotation.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/Annotation.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/Annotation.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ArrayElementValue.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ArrayElementValue.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ArrayElementValue.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ArrayElementValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ClassElementValue.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ClassElementValue.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ClassElementValue.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ClassElementValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ConstantElementValue.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ConstantElementValue.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ConstantElementValue.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ConstantElementValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ElementValue.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ElementValue.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ElementValue.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ElementValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -31,6 +31,12 @@ */ public abstract class ParameterAnnotationsAttribute extends Attribute { + // Note that the java compilers of JDK 1.5+ and of Eclipse count the + // number of parameters of constructors of non-static inner classes and + // of enum classes, based on the Signature attribute (if any), which + // lacks the first one or two synthetic parameters. Unresolved issues: + // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8024694 + // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8024694 public int u1parametersCount; public int[] u2parameterAnnotationsCount; public Annotation[][] parameterAnnotations; diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleTypeAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleTypeAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleTypeAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeInvisibleTypeAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleTypeAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleTypeAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleTypeAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/RuntimeVisibleTypeAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/CatchTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/CatchTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/CatchTargetInfo.java 2018-02-13 17:27:36.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/CatchTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/EmptyTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/EmptyTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/EmptyTargetInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/EmptyTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/FormalParameterTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/FormalParameterTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/FormalParameterTargetInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/FormalParameterTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetElement.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetElement.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetElement.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetElement.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetInfo.java 2018-02-13 17:27:36.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/LocalVariableTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/OffsetTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/OffsetTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/OffsetTargetInfo.java 2018-02-13 17:27:36.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/OffsetTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/SuperTypeTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/SuperTypeTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/SuperTypeTargetInfo.java 2018-02-13 17:35:56.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/SuperTypeTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -31,7 +31,7 @@ */ public class SuperTypeTargetInfo extends TargetInfo { - public final int EXTENDS_INDEX = 65535; + public static final int EXTENDS_INDEX = 65535; public int u2superTypeIndex; diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TargetInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/ThrowsTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/ThrowsTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/ThrowsTargetInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/ThrowsTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TypeArgumentTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TypeArgumentTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TypeArgumentTargetInfo.java 2018-02-13 17:27:36.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TypeArgumentTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TypeParameterBoundTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TypeParameterBoundTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TypeParameterBoundTargetInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TypeParameterBoundTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TypeParameterTargetInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TypeParameterTargetInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/TypeParameterTargetInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/TypeParameterTargetInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/visitor/LocalVariableTargetElementVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/visitor/LocalVariableTargetElementVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/visitor/LocalVariableTargetElementVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/visitor/LocalVariableTargetElementVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/visitor/TargetInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/visitor/TargetInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/target/visitor/TargetInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/target/visitor/TargetInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/TypeAnnotation.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/TypeAnnotation.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/TypeAnnotation.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/TypeAnnotation.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/TypeAnnotationsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/TypeAnnotationsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/TypeAnnotationsAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/TypeAnnotationsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/TypePathInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/TypePathInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/TypePathInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/TypePathInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AllElementValueVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AllElementValueVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AllElementValueVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AllElementValueVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedClassVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedMemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedMemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedMemberVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationToAnnotatedMemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/MultiAnnotationVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/MultiAnnotationVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/MultiAnnotationVisitor.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/MultiAnnotationVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.attribute.annotation.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.util.ArrayUtil; + +/** + * This AnnotationVisitor delegates all visits to each AnnotationVisitor + * in a given list. + * + * @author Thomas Neidhart + */ +public class MultiAnnotationVisitor implements AnnotationVisitor +{ + private AnnotationVisitor[] annotationVisitors; + private int annotationVisitorCount; + + + public MultiAnnotationVisitor() + { + this.annotationVisitors = new AnnotationVisitor[16]; + } + + + public MultiAnnotationVisitor(AnnotationVisitor... annotationVisitors) + { + this.annotationVisitors = annotationVisitors; + this.annotationVisitorCount = annotationVisitors.length; + } + + + public void addAnnotationVisitor(AnnotationVisitor annotationVisitor) + { + annotationVisitors = + ArrayUtil.add(annotationVisitors, + annotationVisitorCount++, + annotationVisitor); + } + + + // Implementations for AnnotationVisitor. + + + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + for (int index = 0; index < annotationVisitorCount; index++) + { + annotationVisitors[index].visitAnnotation(clazz, annotation); + } + } + + + public void visitAnnotation(Clazz clazz, Field field, Annotation annotation) + { + for (int index = 0; index < annotationVisitorCount; index++) + { + annotationVisitors[index].visitAnnotation(clazz, field, annotation); + } + } + + + public void visitAnnotation(Clazz clazz, Method method, Annotation annotation) + { + for (int index = 0; index < annotationVisitorCount; index++) + { + annotationVisitors[index].visitAnnotation(clazz, method, annotation); + } + } + + + public void visitAnnotation(Clazz clazz, Method method, int parameterIndex, Annotation annotation) + { + for (int index = 0; index < annotationVisitorCount; index++) + { + annotationVisitors[index].visitAnnotation(clazz, method, parameterIndex, annotation); + } + } + + + public void visitAnnotation(Clazz clazz, Method method, CodeAttribute codeAttribute, Annotation annotation) + { + for (int index = 0; index < annotationVisitorCount; index++) + { + annotationVisitors[index].visitAnnotation(clazz, method, codeAttribute, annotation); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/TypeAnnotationVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/TypeAnnotationVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/TypeAnnotationVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/TypeAnnotationVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/TypePathInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/TypePathInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/annotation/visitor/TypePathInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/annotation/visitor/TypePathInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/Attribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/Attribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/Attribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/Attribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/BootstrapMethodInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/BootstrapMethodInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/BootstrapMethodInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/BootstrapMethodInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -61,6 +61,17 @@ } + /** + * Applies the given constant pool visitor to the method handle of the + * bootstrap method. + */ + public void methodHandleAccept(Clazz clazz, ConstantVisitor constantVisitor) + { + clazz.constantPoolEntryAccept(u2methodHandleIndex, + constantVisitor); + } + + /** * Applies the given constant pool visitor to the argument constants of the * bootstrap method. diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/CodeAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/CodeAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/CodeAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/CodeAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/ConstantValueAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/ConstantValueAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/ConstantValueAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/ConstantValueAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/DeprecatedAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/DeprecatedAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/DeprecatedAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/DeprecatedAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/EnclosingMethodAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/EnclosingMethodAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/EnclosingMethodAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/EnclosingMethodAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/ExceptionInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/ExceptionInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/ExceptionInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/ExceptionInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/ExceptionsAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/ExceptionsAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/ExceptionsAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/ExceptionsAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/ExtendedLineNumberInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/ExtendedLineNumberInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/ExtendedLineNumberInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/ExtendedLineNumberInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/InnerClassesAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/InnerClassesAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/InnerClassesAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/InnerClassesAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -55,7 +55,6 @@ this.classes = classes; } - // // Implementations for Attribute. diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/InnerClassesInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/InnerClassesInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/InnerClassesInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/InnerClassesInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/LineNumberInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/LineNumberInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/LineNumberInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/LineNumberInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/LineNumberTableAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/LineNumberTableAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/LineNumberTableAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/LineNumberTableAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableInfo.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableTableAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableTableAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableTableAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableTableAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableTypeInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableTypeInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableTypeInfo.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableTypeInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -134,8 +134,8 @@ return this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 : - this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 : this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 : + this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 : this.u2signatureIndex < other.u2signatureIndex ? -1 : this.u2signatureIndex > other.u2signatureIndex ? 1 : this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 : 0; diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/MethodParametersAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/MethodParametersAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/MethodParametersAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/MethodParametersAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/ExportsInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/ExportsInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/ExportsInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/ExportsInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/ModuleAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/ModuleAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/ModuleAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/ModuleAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/ModuleMainClassAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/ModuleMainClassAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/ModuleMainClassAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/ModuleMainClassAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/ModulePackagesAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/ModulePackagesAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/ModulePackagesAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/ModulePackagesAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/OpensInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/OpensInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/OpensInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/OpensInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/ProvidesInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/ProvidesInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/ProvidesInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/ProvidesInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/RequiresInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/RequiresInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/RequiresInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/RequiresInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllExportsInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllExportsInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllExportsInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllExportsInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllOpensInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllOpensInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllOpensInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllOpensInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllProvidesInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllProvidesInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllProvidesInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllProvidesInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllRequiresInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllRequiresInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/AllRequiresInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/AllRequiresInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/ExportsInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/ExportsInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/ExportsInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/ExportsInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/OpensInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/OpensInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/OpensInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/OpensInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/ProvidesInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/ProvidesInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/ProvidesInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/ProvidesInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/RequiresInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/RequiresInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/module/visitor/RequiresInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/module/visitor/RequiresInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/NestHostAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/NestHostAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/NestHostAttribute.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/NestHostAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.attribute; + +import proguard.classfile.Clazz; +import proguard.classfile.attribute.visitor.AttributeVisitor; + +/** + * This Attribute represents a nest host attribute. + * + * @author Eric Lafortune + */ +public class NestHostAttribute extends Attribute +{ + public int u2hostClassIndex; + + + /** + * Creates an uninitialized NestHostAttribute. + */ + public NestHostAttribute() + { + } + + + /** + * Creates an initialized NestHostAttribute. + */ + public NestHostAttribute(int u2attributeNameIndex, + int u2hostClassIndex) + { + super(u2attributeNameIndex); + + this.u2hostClassIndex = u2hostClassIndex; + } + + + // Implementations for Attribute. + + public void accept(Clazz clazz, AttributeVisitor attributeVisitor) + { + attributeVisitor.visitNestHostAttribute(clazz, this); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/NestMembersAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/NestMembersAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/NestMembersAttribute.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/NestMembersAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.attribute; + +import proguard.classfile.Clazz; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.constant.visitor.ConstantVisitor; + +/** + * This Attribute represents a nest host attribute. + * + * @author Eric Lafortune + */ +public class NestMembersAttribute extends Attribute +{ + public int u2classesCount; + public int[] u2classes; + + + /** + * Creates an uninitialized NestMembersAttribute. + */ + public NestMembersAttribute() + { + } + + + /** + * Creates an initialized NestMembersAttribute. + */ + public NestMembersAttribute(int u2attributeNameIndex, + int u2classesCount, + int[] u2classes) + { + super(u2attributeNameIndex); + + this.u2classesCount = u2classesCount; + this.u2classes = u2classes; + } + + + // Implementations for Attribute. + + public void accept(Clazz clazz, AttributeVisitor attributeVisitor) + { + attributeVisitor.visitNestMembersAttribute(clazz, this); + } + + + /** + * Applies the given visitor to all member class constants. + */ + public void memberClassConstantsAccept(Clazz clazz, ConstantVisitor constantVisitor) + { + for (int index = 0; index < u2classesCount; index++) + { + clazz.constantPoolEntryAccept(u2classes[index], constantVisitor); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/ParameterInfo.java proguard-6.2.0/core/src/proguard/classfile/attribute/ParameterInfo.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/ParameterInfo.java 2018-02-03 20:15:06.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/ParameterInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/DoubleType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/DoubleType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/DoubleType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/DoubleType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/FloatType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/FloatType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/FloatType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/FloatType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/FullFrame.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/FullFrame.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/FullFrame.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/FullFrame.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/IntegerType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/IntegerType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/IntegerType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/IntegerType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/LessZeroFrame.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/LessZeroFrame.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/LessZeroFrame.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/LessZeroFrame.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/LongType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/LongType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/LongType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/LongType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/NullType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/NullType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/NullType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/NullType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/ObjectType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/ObjectType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/ObjectType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/ObjectType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/SameOneFrame.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/SameOneFrame.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/SameOneFrame.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/SameOneFrame.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/SameZeroFrame.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/SameZeroFrame.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/SameZeroFrame.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/SameZeroFrame.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/StackMapAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/StackMapAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/StackMapAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/StackMapAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/StackMapFrame.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/StackMapFrame.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/StackMapFrame.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/StackMapFrame.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/TopType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/TopType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/TopType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/TopType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/UninitializedThisType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/UninitializedThisType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/UninitializedThisType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/UninitializedThisType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/UninitializedType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/UninitializedType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/UninitializedType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/UninitializedType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/VerificationType.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/VerificationType.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/VerificationType.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/VerificationType.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/SignatureAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/SignatureAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/SignatureAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/SignatureAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/SourceDirAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/SourceDirAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/SourceDirAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/SourceDirAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/SourceFileAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/SourceFileAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/SourceFileAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/SourceFileAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/SyntheticAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/SyntheticAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/SyntheticAttribute.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/SyntheticAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/UnknownAttribute.java proguard-6.2.0/core/src/proguard/classfile/attribute/UnknownAttribute.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/UnknownAttribute.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/UnknownAttribute.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllLineNumberInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllLineNumberInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AllLineNumberInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AllLineNumberInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeCounter.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeCounter.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeCounter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeCounter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -143,6 +143,24 @@ } } + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + if (accepted(clazz, nestHostAttribute)) + { + attributeVisitor.visitNestHostAttribute(clazz, nestHostAttribute); + } + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + if (accepted(clazz, nestMembersAttribute)) + { + attributeVisitor.visitNestMembersAttribute(clazz, nestMembersAttribute); + } + } + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeToClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeToClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeToClassVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeToClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/AttributeVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/AttributeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -42,6 +42,8 @@ public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute); public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute); public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute); + public void visitNestHostAttribute( Clazz clazz, NestHostAttribute nestHostAttribute); + public void visitNestMembersAttribute( Clazz clazz, NestMembersAttribute nestMembersAttribute); public void visitModuleAttribute( Clazz clazz, ModuleAttribute moduleAttribute); public void visitModuleMainClassAttribute( Clazz clazz, ModuleMainClassAttribute moduleMainClassAttribute); public void visitModulePackagesAttribute( Clazz clazz, ModulePackagesAttribute modulePackagesAttribute); diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java 2018-04-12 10:46:04.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/DebugAttributeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/DebugAttributeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/DebugAttributeVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/DebugAttributeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -157,6 +157,26 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + long startTime = startTime(); + + attributeVisitor.visitNestHostAttribute(clazz, nestHostAttribute); + + checkTime(clazz, nestHostAttribute, startTime); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + long startTime = startTime(); + + attributeVisitor.visitNestMembersAttribute(clazz, nestMembersAttribute); + + checkTime(clazz, nestMembersAttribute, startTime); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { long startTime = startTime(); diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/InstructionToAttributeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/InstructionToAttributeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/InstructionToAttributeVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/InstructionToAttributeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LineNumberRangeFinder.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LineNumberRangeFinder.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LineNumberRangeFinder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LineNumberRangeFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -117,6 +117,24 @@ } } + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + for (int index = 0; index < attributeVisitorCount; index++) + { + attributeVisitors[index].visitNestHostAttribute(clazz, nestHostAttribute); + } + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + for (int index = 0; index < attributeVisitorCount; index++) + { + attributeVisitors[index].visitNestMembersAttribute(clazz, nestMembersAttribute); + } + } + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -94,6 +94,21 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + attributeVisitor.visitNestHostAttribute(clazz, nestHostAttribute); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + if (nestMembersAttribute.u2classesCount > 0) + { + attributeVisitor.visitNestMembersAttribute(clazz, nestMembersAttribute); + } + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { if (moduleAttribute.u2requiresCount > 0 || diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/ParameterInfoVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/ParameterInfoVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/ParameterInfoVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/ParameterInfoVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -127,6 +127,24 @@ } } + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + if (requiredAttributeVisitor != null) + { + requiredAttributeVisitor.visitNestHostAttribute(clazz, nestHostAttribute); + } + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + if (requiredAttributeVisitor != null) + { + requiredAttributeVisitor.visitNestMembersAttribute(clazz, nestMembersAttribute); + } + } + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/SingleTimeAttributeVisitor.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/SingleTimeAttributeVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/SingleTimeAttributeVisitor.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/SingleTimeAttributeVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,559 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.attribute.visitor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.module.*; +import proguard.classfile.attribute.preverification.*; + +/** + * This AttributeVisitor delegates all visits to a given AttributeVisitor, + * although only once to the same attribute in a row. + * + * It can for example be used to lazily apply a visitor in a place where it + * would be called multiple times. + * + * @author Eric Lafortune + */ +public class SingleTimeAttributeVisitor +implements AttributeVisitor +{ + private final AttributeVisitor attributeVisitor; + + private Attribute lastVisitedAttribute; + + + public SingleTimeAttributeVisitor(AttributeVisitor attributeVisitor) + { + this.attributeVisitor = attributeVisitor; + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) + { + if (!unknownAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitUnknownAttribute(clazz, unknownAttribute); + + lastVisitedAttribute = unknownAttribute; + } + } + + @Override + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + if (!bootstrapMethodsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute); + + lastVisitedAttribute = bootstrapMethodsAttribute; + } + } + + @Override + public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) + { + if (!sourceFileAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSourceFileAttribute(clazz, sourceFileAttribute); + + lastVisitedAttribute = sourceFileAttribute; + } + } + + @Override + public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) + { + if (!sourceDirAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSourceDirAttribute(clazz, sourceDirAttribute); + + lastVisitedAttribute = sourceDirAttribute; + } + } + + @Override + public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) + { + if (!innerClassesAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitInnerClassesAttribute(clazz, innerClassesAttribute); + + lastVisitedAttribute = innerClassesAttribute; + } + } + + @Override + public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) + { + if (!enclosingMethodAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitEnclosingMethodAttribute(clazz, enclosingMethodAttribute); + + lastVisitedAttribute = enclosingMethodAttribute; + } + } + + @Override + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + if (!nestHostAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitNestHostAttribute(clazz, nestHostAttribute); + + lastVisitedAttribute = nestHostAttribute; + } + } + + @Override + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + if (!nestMembersAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitNestMembersAttribute(clazz, nestMembersAttribute); + + lastVisitedAttribute = nestMembersAttribute; + } + } + + @Override + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) + { + if (!moduleAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitModuleAttribute(clazz, moduleAttribute); + + lastVisitedAttribute = moduleAttribute; + } + } + + @Override + public void visitModuleMainClassAttribute(Clazz clazz, ModuleMainClassAttribute moduleMainClassAttribute) + { + if (!moduleMainClassAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitModuleMainClassAttribute(clazz, moduleMainClassAttribute); + + lastVisitedAttribute = moduleMainClassAttribute; + } + } + + @Override + public void visitModulePackagesAttribute(Clazz clazz, ModulePackagesAttribute modulePackagesAttribute) + { + if (!modulePackagesAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitModulePackagesAttribute(clazz, modulePackagesAttribute); + + lastVisitedAttribute = modulePackagesAttribute; + } + } + + @Override + public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) + { + if (!deprecatedAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitDeprecatedAttribute(clazz, deprecatedAttribute); + + lastVisitedAttribute = deprecatedAttribute; + } + } + + @Override + public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute) + { + if (!deprecatedAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitDeprecatedAttribute(clazz, field, deprecatedAttribute); + + lastVisitedAttribute = deprecatedAttribute; + } + } + + @Override + public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute) + { + if (!deprecatedAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitDeprecatedAttribute(clazz, method, deprecatedAttribute); + + lastVisitedAttribute = deprecatedAttribute; + } + } + + @Override + public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) + { + if (!syntheticAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSyntheticAttribute(clazz, syntheticAttribute); + + lastVisitedAttribute = syntheticAttribute; + } + } + + @Override + public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute) + { + if (!syntheticAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSyntheticAttribute(clazz, field, syntheticAttribute); + + lastVisitedAttribute = syntheticAttribute; + } + } + + @Override + public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute) + { + if (!syntheticAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSyntheticAttribute(clazz, method, syntheticAttribute); + + lastVisitedAttribute = syntheticAttribute; + } + } + + @Override + public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) + { + if (!signatureAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSignatureAttribute(clazz, signatureAttribute); + + lastVisitedAttribute = signatureAttribute; + } + } + + @Override + public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute) + { + if (!signatureAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSignatureAttribute(clazz, field, signatureAttribute); + + lastVisitedAttribute = signatureAttribute; + } + } + + @Override + public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute) + { + if (!signatureAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitSignatureAttribute(clazz, method, signatureAttribute); + + lastVisitedAttribute = signatureAttribute; + } + } + + @Override + public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) + { + if (!constantValueAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitConstantValueAttribute(clazz, field, constantValueAttribute); + + lastVisitedAttribute = constantValueAttribute; + } + } + + @Override + public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute) + { + if (!methodParametersAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitMethodParametersAttribute(clazz, method, methodParametersAttribute); + + lastVisitedAttribute = methodParametersAttribute; + } + } + + @Override + public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) + { + if (!exceptionsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitExceptionsAttribute(clazz, method, exceptionsAttribute); + + lastVisitedAttribute = exceptionsAttribute; + } + } + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + if (!codeAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitCodeAttribute(clazz, method, codeAttribute); + + lastVisitedAttribute = codeAttribute; + } + } + + @Override + public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) + { + if (!stackMapAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitStackMapAttribute(clazz, method, codeAttribute, stackMapAttribute); + + lastVisitedAttribute = stackMapAttribute; + } + } + + @Override + public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) + { + if (!stackMapTableAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitStackMapTableAttribute(clazz, method, codeAttribute, stackMapTableAttribute); + + lastVisitedAttribute = stackMapTableAttribute; + } + } + + @Override + public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) + { + if (!lineNumberTableAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitLineNumberTableAttribute(clazz, method, codeAttribute, lineNumberTableAttribute); + + lastVisitedAttribute = lineNumberTableAttribute; + } + } + + @Override + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + if (!localVariableTableAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitLocalVariableTableAttribute(clazz, method, codeAttribute, localVariableTableAttribute); + + lastVisitedAttribute = localVariableTableAttribute; + } + } + + @Override + public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) + { + if (!localVariableTypeTableAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, localVariableTypeTableAttribute); + + lastVisitedAttribute = localVariableTypeTableAttribute; + } + } + + @Override + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + if (!runtimeVisibleAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, runtimeVisibleAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + if (!runtimeVisibleAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, field, runtimeVisibleAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + if (!runtimeVisibleAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, method, runtimeVisibleAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + if (!runtimeInvisibleAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, runtimeInvisibleAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + if (!runtimeInvisibleAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, field, runtimeInvisibleAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + if (!runtimeInvisibleAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, method, runtimeInvisibleAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute) + { + if (!runtimeVisibleParameterAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleParameterAnnotationsAttribute(clazz, method, runtimeVisibleParameterAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleParameterAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute) + { + if (!runtimeInvisibleParameterAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleParameterAnnotationsAttribute(clazz, method, runtimeInvisibleParameterAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleParameterAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) + { + if (!runtimeVisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, runtimeVisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) + { + if (!runtimeVisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, field, runtimeVisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) + { + if (!runtimeVisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, method, runtimeVisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) + { + if (!runtimeVisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, method, codeAttribute, runtimeVisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeVisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) + { + if (!runtimeInvisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, runtimeInvisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) + { + if (!runtimeInvisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, field, runtimeInvisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) + { + if (!runtimeInvisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, method, runtimeInvisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) + { + if (!runtimeInvisibleTypeAnnotationsAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, method, codeAttribute, runtimeInvisibleTypeAnnotationsAttribute); + + lastVisitedAttribute = runtimeInvisibleTypeAnnotationsAttribute; + } + } + + @Override + public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) + { + if (!annotationDefaultAttribute.equals(lastVisitedAttribute)) + { + attributeVisitor.visitAnnotationDefaultAttribute(clazz, method, annotationDefaultAttribute); + + lastVisitedAttribute = annotationDefaultAttribute; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/StackSizeComputer.java proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/StackSizeComputer.java --- proguard-6.0.3/core/src/proguard/classfile/attribute/visitor/StackSizeComputer.java 2018-01-24 21:44:42.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/attribute/visitor/StackSizeComputer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/ClassConstants.java proguard-6.2.0/core/src/proguard/classfile/ClassConstants.java --- proguard-6.0.3/core/src/proguard/classfile/ClassConstants.java 2018-04-01 22:48:46.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/ClassConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -56,6 +56,12 @@ 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_11_MAJOR = 55; + public static final int CLASS_VERSION_11_MINOR = 0; + public static final int CLASS_VERSION_12_MAJOR = 56; + public static final int CLASS_VERSION_12_MINOR = 0; + public static final int CLASS_VERSION_13_MAJOR = 57; + public static final int CLASS_VERSION_13_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; @@ -67,6 +73,9 @@ 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 CLASS_VERSION_11 = (CLASS_VERSION_11_MAJOR << 16) | CLASS_VERSION_11_MINOR; + public static final int CLASS_VERSION_12 = (CLASS_VERSION_12_MAJOR << 16) | CLASS_VERSION_12_MINOR; + public static final int CLASS_VERSION_13 = (CLASS_VERSION_13_MAJOR << 16) | CLASS_VERSION_13_MINOR; public static final int ACC_PUBLIC = 0x0001; public static final int ACC_PRIVATE = 0x0002; @@ -155,6 +164,7 @@ public static final int CONSTANT_NameAndType = 12; public static final int CONSTANT_MethodHandle = 15; public static final int CONSTANT_MethodType = 16; + public static final int CONSTANT_Dynamic = 17; public static final int CONSTANT_InvokeDynamic = 18; public static final int CONSTANT_Module = 19; public static final int CONSTANT_Package = 20; @@ -180,6 +190,8 @@ public static final String ATTR_SourceDir = "SourceDir"; public static final String ATTR_InnerClasses = "InnerClasses"; public static final String ATTR_EnclosingMethod = "EnclosingMethod"; + public static final String ATTR_NestHost = "NestHost"; + public static final String ATTR_NestMembers = "NestMembers"; public static final String ATTR_Deprecated = "Deprecated"; public static final String ATTR_Synthetic = "Synthetic"; public static final String ATTR_Signature = "Signature"; @@ -255,6 +267,7 @@ public static final String NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable"; public static final String NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable"; public static final String NAME_JAVA_LANG_EXCEPTION = "java/lang/Exception"; + public static final String NAME_JAVA_LANG_NUMBER_FORMAT_EXCEPTION = "java/lang/NumberFormatException"; public static final String NAME_JAVA_LANG_CLASS = "java/lang/Class"; public static final String TYPE_JAVA_LANG_CLASS = "Ljava/lang/Class;"; public static final String NAME_JAVA_LANG_CLASS_LOADER = "java/lang/ClassLoader"; @@ -267,6 +280,7 @@ public static final String NAME_JAVA_LANG_INVOKE_STRING_CONCAT_FACTORY = "java/lang/invoke/StringConcatFactory"; public static final String NAME_JAVA_LANG_VOID = "java/lang/Void"; public static final String NAME_JAVA_LANG_BOOLEAN = "java/lang/Boolean"; + public static final String TYPE_JAVA_LANG_BOOLEAN = "Ljava/lang/Boolean;"; public static final String NAME_JAVA_LANG_BYTE = "java/lang/Byte"; public static final String NAME_JAVA_LANG_SHORT = "java/lang/Short"; public static final String NAME_JAVA_LANG_CHARACTER = "java/lang/Character"; @@ -289,6 +303,9 @@ public static final String NAME_JAVA_UTIL_MAP = "java/util/Map"; public static final String TYPE_JAVA_UTIL_MAP = "Ljava/util/Map;"; public static final String NAME_JAVA_UTIL_HASH_MAP = "java/util/HashMap"; + public static final String NAME_JAVA_UTIL_LIST = "java/util/List"; + public static final String TYPE_JAVA_UTIL_LIST = "Ljava/util/List;"; + public static final String NAME_JAVA_UTIL_ARRAY_LIST = "java/util/ArrayList"; public static final String NAME_ANDROID_UTIL_FLOAT_MATH = "android/util/FloatMath"; @@ -381,9 +398,39 @@ public static final String METHOD_TYPE_ACCESSIBLE_OBJECT_SET_ACCESSIBLE = "(Z)V"; public static final String METHOD_NAME_GET_CAUSE = "getCause"; public static final String METHOD_TYPE_GET_CAUSE = "()Ljava/lang/Throwable;"; + public static final String METHOD_TYPE_INIT_THROWABLE = "(Ljava/lang/Throwable;)V"; public static final String METHOD_NAME_MAKE_CONCAT = "makeConcat"; public static final String METHOD_NAME_MAKE_CONCAT_WITH_CONSTANTS = "makeConcatWithConstants"; + public static final String METHOD_TYPE_INIT_COLLECTION = "(Ljava/util/Collection;)V"; + public static final String METHOD_NAME_ADD = "add"; + public static final String METHOD_TYPE_ADD = "(Ljava/lang/Object;)Z"; + public static final String METHOD_NAME_ADD_ALL = "addAll"; + public static final String METHOD_TYPE_ADD_ALL = "(Ljava/util/Collection;)Z"; + public static final String METHOD_NAME_IS_EMPTY = "isEmpty"; + public static final String METHOD_TYPE_IS_EMPTY = "()Z"; + public static final String METHOD_NAME_MAP_PUT = "put"; + public static final String METHOD_TYPE_MAP_PUT = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; + public static final String METHOD_NAME_MAP_GET = "get"; + public static final String METHOD_TYPE_MAP_GET = "(Ljava/lang/Object;)Ljava/lang/Object;"; + + public static final String METHOD_NAME_BOOLEAN_VALUE = "booleanValue"; + public static final String METHOD_TYPE_BOOLEAN_VALUE = "()Z"; + public static final String METHOD_NAME_CHAR_VALUE = "charValue"; + public static final String METHOD_TYPE_CHAR_VALUE = "()C"; + public static final String METHOD_NAME_SHORT_VALUE = "shortValue"; + public static final String METHOD_TYPE_SHORT_VALUE = "()S"; + public static final String METHOD_NAME_INT_VALUE = "intValue"; + public static final String METHOD_TYPE_INT_VALUE = "()I"; + public static final String METHOD_NAME_BYTE_VALUE = "byteValue"; + public static final String METHOD_TYPE_BYTE_VALUE = "()B"; + public static final String METHOD_NAME_LONG_VALUE = "longValue"; + public static final String METHOD_TYPE_LONG_VALUE = "()J"; + public static final String METHOD_NAME_FLOAT_VALUE = "floatValue"; + public static final String METHOD_TYPE_FLOAT_VALUE = "()F"; + public static final String METHOD_NAME_DOUBLE_VALUE = "doubleValue"; + public static final String METHOD_TYPE_DOUBLE_VALUE = "()D"; + // Serialization methods. public static final String METHOD_NAME_READ_OBJECT = "readObject"; public static final String METHOD_TYPE_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V"; @@ -404,8 +451,15 @@ public static final String METHOD_NAME_NEW_INSTANCE = "newInstance"; public static final String METHOD_TYPE_NEW_INSTANCE = "()Ljava/lang/Object;"; - public static final String METHOD_NAME_VALUE_OF = "valueOf"; - public static final String METHOD_TYPE_VALUE_OF = "(I)Ljava/lang/Integer;"; + public static final String METHOD_NAME_VALUE_OF = "valueOf"; + public static final String METHOD_TYPE_VALUE_OF_BOOLEAN = "(Z)Ljava/lang/Boolean;"; + public static final String METHOD_TYPE_VALUE_OF_CHAR = "(C)Ljava/lang/Character;"; + public static final String METHOD_TYPE_VALUE_OF_BYTE = "(B)Ljava/lang/Byte;"; + public static final String METHOD_TYPE_VALUE_OF_SHORT = "(S)Ljava/lang/Short;"; + public static final String METHOD_TYPE_VALUE_OF_INT = "(I)Ljava/lang/Integer;"; + public static final String METHOD_TYPE_VALUE_OF_LONG = "(J)Ljava/lang/Long;"; + public static final String METHOD_TYPE_VALUE_OF_FLOAT = "(F)Ljava/lang/Float;"; + public static final String METHOD_TYPE_VALUE_OF_DOUBLE = "(D)Ljava/lang/Double;"; public static final String FIELD_NAME_TYPE = "TYPE"; public static final String FIELD_TYPE_TYPE = "Ljava/lang/Class;"; @@ -415,6 +469,7 @@ public static final String METHOD_TYPE_LENGTH = "()I"; public static final String METHOD_NAME_VALUEOF = "valueOf"; public static final String METHOD_TYPE_VALUEOF_BOOLEAN = "(Z)Ljava/lang/String;"; + public static final String METHOD_TYPE_TOSTRING_BOOLEAN = "(Z)Ljava/lang/String;"; public static final String METHOD_TYPE_VALUEOF_CHAR = "(C)Ljava/lang/String;"; public static final String METHOD_TYPE_VALUEOF_INT = "(I)Ljava/lang/String;"; public static final String METHOD_TYPE_VALUEOF_LONG = "(J)Ljava/lang/String;"; @@ -485,6 +540,8 @@ public static final int MAXIMUM_BOOLEAN_AS_STRING_LENGTH = 5; // false public static final int MAXIMUM_CHAR_AS_STRING_LENGTH = 1; // any char + public static final int MAXIMUM_BYTE_AS_STRING_LENGTH = 3; // 255 + public static final int MAXIMUM_SHORT_AS_STRING_LENGTH = 6; // -32768 public static final int MAXIMUM_INT_AS_STRING_LENGTH = 11; //-2147483648 public static final int MAXIMUM_LONG_AS_STRING_LENGTH = 20; //-9223372036854775808 public static final int MAXIMUM_FLOAT_AS_STRING_LENGTH = 13; //-3.4028235E38 diff -Nru proguard-6.0.3/core/src/proguard/classfile/ClassPool.java proguard-6.2.0/core/src/proguard/classfile/ClassPool.java --- proguard-6.0.3/core/src/proguard/classfile/ClassPool.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/ClassPool.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -21,6 +21,7 @@ package proguard.classfile; import proguard.classfile.visitor.*; +import proguard.util.*; import java.util.*; @@ -144,6 +145,49 @@ } } + + /** + * Applies the given ClassVisitor to all matching classes in the class pool. + */ + public void classesAccept(String classNameFilter, + ClassVisitor classVisitor) + { + classesAccept(new ListParser(new ClassNameParser()).parse(classNameFilter), + classVisitor); + } + + + /** + * Applies the given ClassVisitor to all matching classes in the class pool. + */ + public void classesAccept(List classNameFilter, + ClassVisitor classVisitor) + { + classesAccept(new ListParser(new ClassNameParser()).parse(classNameFilter), + classVisitor); + } + + + /** + * Applies the given ClassVisitor to all matching classes in the class pool. + */ + public void classesAccept(StringMatcher classNameFilter, + ClassVisitor classVisitor) + { + Iterator iterator = classes.entrySet().iterator(); + while (iterator.hasNext()) + { + Map.Entry entry = (Map.Entry)iterator.next(); + String className = (String )entry.getKey(); + + if (classNameFilter.matches(className)) + { + Clazz clazz = (Clazz)entry.getValue(); + clazz.accept(classVisitor); + } + } + } + /** * Applies the given ClassVisitor to the class with the given name, diff -Nru proguard-6.0.3/core/src/proguard/classfile/Clazz.java proguard-6.2.0/core/src/proguard/classfile/Clazz.java --- proguard-6.0.3/core/src/proguard/classfile/Clazz.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/Clazz.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/ClassConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/ClassConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/ClassConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/ClassConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/Constant.java proguard-6.2.0/core/src/proguard/classfile/constant/Constant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/Constant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/Constant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/DoubleConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/DoubleConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/DoubleConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/DoubleConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/DynamicConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/DynamicConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/DynamicConstant.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/DynamicConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,148 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.constant; + +import proguard.classfile.*; +import proguard.classfile.constant.visitor.*; +import proguard.classfile.visitor.ClassVisitor; + +/** + * This Constant represents a dynamic constant in the constant pool. + * + * @author Eric Lafortune + */ +public class DynamicConstant extends Constant +{ + public int u2bootstrapMethodAttributeIndex; + public int u2nameAndTypeIndex; + + /** + * An extra field pointing to the Clazz objects referenced in the + * descriptor string. This field is filled out by the {@link + * proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}. + * References to primitive types are ignored. + */ + public Clazz[] referencedClasses; + + + /** + * Creates an uninitialized InvokeDynamicConstant. + */ + public DynamicConstant() + { + } + + + /** + * Creates a new InvokeDynamicConstant with the given bootstrap method + * and name-and-type indices. + * @param u2bootstrapMethodAttributeIndex the index of the bootstrap method + * entry in the bootstrap methods + * attribute. + * @param u2nameAndTypeIndex the index of the name and type + * entry in the constant pool. + * @param referencedClasses the classes referenced by the + * type. + */ + public DynamicConstant(int u2bootstrapMethodAttributeIndex, + int u2nameAndTypeIndex, + Clazz[] referencedClasses) + { + this.u2bootstrapMethodAttributeIndex = u2bootstrapMethodAttributeIndex; + this.u2nameAndTypeIndex = u2nameAndTypeIndex; + this.referencedClasses = referencedClasses; + } + + + /** + * Returns the index of the bootstrap method in the bootstrap methods + * attribute of the class. + */ + public int getBootstrapMethodAttributeIndex() + { + return u2bootstrapMethodAttributeIndex; + } + + /** + * Returns the name-and-type index. + */ + public int getNameAndTypeIndex() + { + return u2nameAndTypeIndex; + } + + /** + * Returns the method name. + */ + public String getName(Clazz clazz) + { + return clazz.getName(u2nameAndTypeIndex); + } + + /** + * Returns the method type. + */ + public String getType(Clazz clazz) + { + return clazz.getType(u2nameAndTypeIndex); + } + + + /** + * Lets the Clazz objects referenced in the descriptor string + * accept the given visitor. + */ + public void referencedClassesAccept(ClassVisitor classVisitor) + { + if (referencedClasses != null) + { + for (int index = 0; index < referencedClasses.length; index++) + { + if (referencedClasses[index] != null) + { + referencedClasses[index].accept(classVisitor); + } + } + } + } + + + /** + * Lets the bootstrap method handle constant accept the given visitor. + */ + public void bootstrapMethodHandleAccept(Clazz clazz, ConstantVisitor constantVisitor) + { + new BootstrapMethodHandleTraveler(constantVisitor).visitDynamicConstant(clazz, this); + } + + + // Implementations for Constant. + + public int getTag() + { + return ClassConstants.CONSTANT_Dynamic; + } + + public void accept(Clazz clazz, ConstantVisitor constantVisitor) + { + constantVisitor.visitDynamicConstant(clazz, this); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/FieldrefConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/FieldrefConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/FieldrefConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/FieldrefConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/FloatConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/FloatConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/FloatConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/FloatConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/IntegerConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/IntegerConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/IntegerConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/IntegerConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/InterfaceMethodrefConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/InterfaceMethodrefConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/InterfaceMethodrefConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/InterfaceMethodrefConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/InvokeDynamicConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/InvokeDynamicConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/InvokeDynamicConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/InvokeDynamicConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/LongConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/LongConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/LongConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/LongConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/MethodHandleConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/MethodHandleConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/MethodHandleConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/MethodHandleConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -118,6 +118,16 @@ } + /** + * Applies the given constant pool visitor to the reference. + */ + public void referenceAccept(Clazz clazz, ConstantVisitor constantVisitor) + { + clazz.constantPoolEntryAccept(u2referenceIndex, + constantVisitor); + } + + // Implementations for Constant. public int getTag() diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/MethodrefConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/MethodrefConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/MethodrefConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/MethodrefConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/MethodTypeConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/MethodTypeConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/MethodTypeConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/MethodTypeConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/ModuleConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/ModuleConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/ModuleConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/ModuleConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/NameAndTypeConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/NameAndTypeConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/NameAndTypeConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/NameAndTypeConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/PackageConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/PackageConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/PackageConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/PackageConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/PrimitiveArrayConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/PrimitiveArrayConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/PrimitiveArrayConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/PrimitiveArrayConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/RefConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/RefConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/RefConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/RefConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/StringConstant.java proguard-6.2.0/core/src/proguard/classfile/constant/StringConstant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/StringConstant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/StringConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/Utf8Constant.java proguard-6.2.0/core/src/proguard/classfile/constant/Utf8Constant.java --- proguard-6.0.3/core/src/proguard/classfile/constant/Utf8Constant.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/Utf8Constant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java 2018-04-12 10:58:05.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/AllConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/AllConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/AllConstantVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/AllConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -60,6 +60,17 @@ public void visitAnyConstant(Clazz clazz, Constant constant) {} + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + // Pass the method index. + bootstrapMethodAttributeIndex = + dynamicConstant.u2bootstrapMethodAttributeIndex; + + // Delegate to the bootstrap method. + clazz.attributesAccept(this); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { // Pass the method index. diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ConstantCounter.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ConstantCounter.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ConstantCounter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ConstantCounter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ConstantTagFilter.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ConstantTagFilter.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ConstantTagFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ConstantTagFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ConstantVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -39,6 +39,7 @@ public void visitPrimitiveArrayConstant( Clazz clazz, PrimitiveArrayConstant primitiveArrayConstant); public void visitStringConstant( Clazz clazz, StringConstant stringConstant); public void visitUtf8Constant( Clazz clazz, Utf8Constant utf8Constant); + public void visitDynamicConstant( Clazz clazz, DynamicConstant dynamicConstant); public void visitInvokeDynamicConstant( Clazz clazz, InvokeDynamicConstant invokeDynamicConstant); public void visitMethodHandleConstant( Clazz clazz, MethodHandleConstant methodHandleConstant); public void visitFieldrefConstant( Clazz clazz, FieldrefConstant fieldrefConstant); diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/MethodrefTraveler.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/MethodrefTraveler.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/MethodrefTraveler.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/MethodrefTraveler.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantElementVisitor.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantElementVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantElementVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantElementVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/PrimitiveArrayConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/constant/visitor/SuperClassConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/constant/visitor/SuperClassConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/constant/visitor/SuperClassConstantVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/constant/visitor/SuperClassConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/AccessFixer.java proguard-6.2.0/core/src/proguard/classfile/editor/AccessFixer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/AccessFixer.java 2018-03-29 10:12:22.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/AccessFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -287,15 +287,21 @@ if (currentAccessLevel < AccessUtil.PUBLIC) { // 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. + // For protected access: + // - The referencing method may not be static. + // - The invoked class must be the referencing class (or a + // subclass, which may be counter-intuitive), to avoid + // invoking protected super methods on instances that are + // not of the referencing type, which the verifier doesn't + // allow. (test2172) [DGD-1258] + // - The class that actually contains the member must be a + // super class. int requiredAccessLevel = programClass.equals(referencingClass) ? AccessUtil.PRIVATE : inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE : (referencingMethodAccessFlags & ClassConstants.ACC_STATIC) == 0 && (referencedClass == null || - referencingClass.extends_(referencedClass)) && + referencedClass.extends_(referencingClass)) && referencingClass.extends_(programClass) ? AccessUtil.PROTECTED : AccessUtil.PUBLIC; diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/AnnotationAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/AnnotationAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/AnnotationAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/AnnotationAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/AnnotationsAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/AnnotationsAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/AnnotationsAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/AnnotationsAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -21,6 +21,7 @@ package proguard.classfile.editor; import proguard.classfile.attribute.annotation.*; +import proguard.util.ArrayUtil; /** * This class can add annotations to a given annotations attribute. @@ -64,4 +65,42 @@ // Add the annotation. annotations[targetAnnotationsAttribute.u2annotationsCount++] = annotation; } + + + /** + * Deletes a given annotation from the annotations attribute. + */ + public void deleteAnnotation(Annotation annotation) + { + int index = findAnnotationIndex(annotation, + targetAnnotationsAttribute.annotations, + targetAnnotationsAttribute.u2annotationsCount); + deleteAnnotation(index); + } + + + /** + * Deletes the annotation at the given idnex from the annotations attribute. + */ + public void deleteAnnotation(int index) + { + ArrayUtil.remove(targetAnnotationsAttribute.annotations, + targetAnnotationsAttribute.u2annotationsCount, + index); + targetAnnotationsAttribute.u2annotationsCount--; + } + + + private int findAnnotationIndex(Annotation annotation, Annotation[] annotations, int annotationCount) + { + for (int index = 0; index < annotationCount; index++) + { + if (annotation == annotations[index]) + { + return index; + } + + } + return -1; + } } \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/AttributeAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/AttributeAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/AttributeAdder.java 2018-02-13 20:15:42.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/AttributeAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -26,6 +26,7 @@ import proguard.classfile.attribute.preverification.*; import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ReferencedClassVisitor; import java.util.Arrays; @@ -169,6 +170,38 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + // Create a copy of the attribute. + NestHostAttribute newNestHostAttribute = + new NestHostAttribute(constantAdder.addConstant(clazz, nestHostAttribute.u2attributeNameIndex), + constantAdder.addConstant(clazz, nestHostAttribute.u2hostClassIndex)); + + // Add it to the target class. + attributesEditor.addAttribute(newNestHostAttribute); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + // Create a copy of the attribute. + NestMembersAttribute newNestMembersAttribute = + new NestMembersAttribute(constantAdder.addConstant(clazz, nestMembersAttribute.u2attributeNameIndex), + 0, + nestMembersAttribute.u2classesCount > 0 ? + new int[nestMembersAttribute.u2classesCount] : + EMPTY_INTS); + + // Add the nest members. + nestMembersAttribute.memberClassConstantsAccept(targetClass, + new NestMemberAdder(targetClass, + newNestMembersAttribute)); + + // Add it to the target class. + attributesEditor.addAttribute(newNestMembersAttribute); + } + + public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) { // Create a copy of the attribute. diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/AttributesEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/AttributesEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/AttributesEditor.java 2018-05-06 20:26:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/AttributesEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/AttributeSorter.java proguard-6.2.0/core/src/proguard/classfile/editor/AttributeSorter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/AttributeSorter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/AttributeSorter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodInfoAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodRemapper.java proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodRemapper.java --- proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodRemapper.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodRemapper.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -67,6 +67,13 @@ public void visitAnyConstant(Clazz clazz, Constant constant) {} + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + dynamicConstant.u2bootstrapMethodAttributeIndex = + remapConstantIndex(dynamicConstant.u2bootstrapMethodAttributeIndex); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { invokeDynamicConstant.u2bootstrapMethodAttributeIndex = diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodsAttributeAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodsAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodsAttributeShrinker.java proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodsAttributeShrinker.java --- proguard-6.0.3/core/src/proguard/classfile/editor/BootstrapMethodsAttributeShrinker.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/BootstrapMethodsAttributeShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/BridgeMethodFixer.java proguard-6.2.0/core/src/proguard/classfile/editor/BridgeMethodFixer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/BridgeMethodFixer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/BridgeMethodFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ClassEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/ClassEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ClassEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ClassEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ClassElementSorter.java proguard-6.2.0/core/src/proguard/classfile/editor/ClassElementSorter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ClassElementSorter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ClassElementSorter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ClassMemberSorter.java proguard-6.2.0/core/src/proguard/classfile/editor/ClassMemberSorter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ClassMemberSorter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ClassMemberSorter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ClassReferenceFixer.java proguard-6.2.0/core/src/proguard/classfile/editor/ClassReferenceFixer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ClassReferenceFixer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ClassReferenceFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -217,6 +217,24 @@ } } + + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + // Has the descriptor changed? + String descriptor = dynamicConstant.getType(clazz); + String newDescriptor = newDescriptor(descriptor, + dynamicConstant.referencedClasses); + + if (!descriptor.equals(newDescriptor)) + { + String name = dynamicConstant.getName(clazz); + + // Refer to a new NameAndType entry. + dynamicConstant.u2nameAndTypeIndex = + new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(name, newDescriptor); + } + } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/CodeAttributeComposer.java proguard-6.2.0/core/src/proguard/classfile/editor/CodeAttributeComposer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/CodeAttributeComposer.java 2018-01-24 21:45:25.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/CodeAttributeComposer.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,6 +22,10 @@ import proguard.classfile.*; import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.target.*; +import proguard.classfile.attribute.annotation.target.visitor.*; +import proguard.classfile.attribute.annotation.visitor.TypeAnnotationVisitor; import proguard.classfile.attribute.preverification.*; import proguard.classfile.attribute.preverification.visitor.*; import proguard.classfile.attribute.visitor.*; @@ -48,7 +52,10 @@ VerificationTypeVisitor, LineNumberInfoVisitor, LocalVariableInfoVisitor, - LocalVariableTypeInfoVisitor + LocalVariableTypeInfoVisitor, + TypeAnnotationVisitor, + TargetInfoVisitor, + LocalVariableTargetElementVisitor { //* private static final boolean DEBUG = false; @@ -647,6 +654,12 @@ } + public void visitAnyTypeAnnotationsAttribute(Clazz clazz, TypeAnnotationsAttribute typeAnnotationsAttribute) + { + typeAnnotationsAttribute.typeAnnotationsAccept(clazz, this); + } + + // Implementations for InstructionVisitor. public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} @@ -822,6 +835,44 @@ } + // Implementations for TypeAnnotationVisitor. + + public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation) + { + // Update all local variable targets. + typeAnnotation.targetInfoAccept(clazz, this); + } + + + // Implementations for TargetInfoVisitor. + + public void visitAnyTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TargetInfo targetInfo) {} + + + public void visitLocalVariableTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo) + { + // Update the offsets of the variables. + localVariableTargetInfo.targetElementsAccept(clazz, method, codeAttribute, typeAnnotation, this); + } + + + public void visitOffsetTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, OffsetTargetInfo offsetTargetInfo) + { + // Update the offset. + offsetTargetInfo.u2offset = newInstructionOffset(offsetTargetInfo.u2offset); + } + + + // Implementations for LocalVariableTargetElementVisitor. + + public void visitLocalVariableTargetElement(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo, LocalVariableTargetElement localVariableTargetElement) + { + // Update the variable start offset and length. + // Be careful to update the length first. + localVariableTargetElement.u2length = newBranchOffset(localVariableTargetElement.u2startPC, localVariableTargetElement.u2length); + localVariableTargetElement.u2startPC = newInstructionOffset(localVariableTargetElement.u2startPC); + } + // Small utility methods. /** diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/CodeAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/CodeAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/CodeAttributeEditor.java 2018-02-01 17:43:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/CodeAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -1498,8 +1498,8 @@ * This pseudo-instruction represents a label that marks an instruction * offset, for use in the context of the code attribute editor only. */ - private static class Label - extends Instruction + public static class Label + extends Instruction { protected final int identifier; diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/CodeAttributeEditorResetter.java proguard-6.2.0/core/src/proguard/classfile/editor/CodeAttributeEditorResetter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/CodeAttributeEditorResetter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/CodeAttributeEditorResetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/CompactCodeAttributeComposer.java proguard-6.2.0/core/src/proguard/classfile/editor/CompactCodeAttributeComposer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/CompactCodeAttributeComposer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/CompactCodeAttributeComposer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ComparableConstant.java proguard-6.2.0/core/src/proguard/classfile/editor/ComparableConstant.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ComparableConstant.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ComparableConstant.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -29,8 +29,8 @@ /** * This class is a Comparable wrapper of Constant - * objects. It can store an index, in order to identify the constant pool - * entry after it has been sorted. The comparison is primarily based on the + * objects. It can store an index, in order to identify the constant pool + * entry after it has been sorted. The comparison is primarily based on the * types of the constant pool entries, and secondarily on the contents of * the constant pool entries. * @@ -43,23 +43,24 @@ private static final int[] PRIORITIES = new int[22]; static { - PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc). - PRIORITIES[ClassConstants.CONSTANT_Float] = 1; - PRIORITIES[ClassConstants.CONSTANT_String] = 2; - PRIORITIES[ClassConstants.CONSTANT_Class] = 3; - PRIORITIES[ClassConstants.CONSTANT_Long] = 4; // Always wide index (ldc2_w). - PRIORITIES[ClassConstants.CONSTANT_Double] = 5; // Always wide index (ldc2_w). - PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index (getfield,...). - PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; // Always wide index (invokespecial,...). - PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; // Always wide index (invokeinterface). - PRIORITIES[ClassConstants.CONSTANT_InvokeDynamic] = 9; // Always wide index (invokedynamic). - PRIORITIES[ClassConstants.CONSTANT_MethodHandle] = 10; - PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 11; - PRIORITIES[ClassConstants.CONSTANT_MethodType] = 12; - PRIORITIES[ClassConstants.CONSTANT_Module] = 13; - PRIORITIES[ClassConstants.CONSTANT_Package] = 14; - PRIORITIES[ClassConstants.CONSTANT_Utf8] = 15; - PRIORITIES[ClassConstants.CONSTANT_PrimitiveArray] = 16; + PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc). + PRIORITIES[ClassConstants.CONSTANT_Float] = 1; + PRIORITIES[ClassConstants.CONSTANT_String] = 2; + PRIORITIES[ClassConstants.CONSTANT_Class] = 3; + PRIORITIES[ClassConstants.CONSTANT_Long] = 4; // Always wide index (ldc2_w). + PRIORITIES[ClassConstants.CONSTANT_Double] = 5; // Always wide index (ldc2_w). + PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index (getfield,...). + PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; // Always wide index (invokespecial,...). + PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; // Always wide index (invokeinterface). + PRIORITIES[ClassConstants.CONSTANT_Dynamic] = 9; // Always wide index (invokedynamic). + PRIORITIES[ClassConstants.CONSTANT_InvokeDynamic] = 10; // Always wide index (invokedynamic). + PRIORITIES[ClassConstants.CONSTANT_MethodHandle] = 11; + PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 12; + PRIORITIES[ClassConstants.CONSTANT_MethodType] = 13; + PRIORITIES[ClassConstants.CONSTANT_Module] = 14; + PRIORITIES[ClassConstants.CONSTANT_Package] = 15; + PRIORITIES[ClassConstants.CONSTANT_Utf8] = 16; + PRIORITIES[ClassConstants.CONSTANT_PrimitiveArray] = 17; } private final Clazz clazz; @@ -104,9 +105,7 @@ { int otherIndex = otherComparableConstant.thisIndex; - return thisIndex < otherIndex ? -1 : - thisIndex == otherIndex ? 0 : - 1; + return Integer.compare(thisIndex, otherIndex); } // Compare based on the tags, if they are different. @@ -115,7 +114,7 @@ if (thisTag != otherTag) { - return PRIORITIES[thisTag] < PRIORITIES[otherTag] ? -1 : 1; + return Integer.compare(PRIORITIES[thisTag], PRIORITIES[otherTag]); } // Otherwise compare based on the contents of the Constant objects. @@ -129,20 +128,14 @@ public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { - int value = integerConstant.getValue(); - int otherValue = ((IntegerConstant)otherConstant).getValue(); - result = value < otherValue ? -1 : - value == otherValue ? 0 : - 1; + result = Integer.compare(integerConstant.getValue(), + ((IntegerConstant)otherConstant).getValue()); } public void visitLongConstant(Clazz clazz, LongConstant longConstant) { - long value = longConstant.getValue(); - long otherValue = ((LongConstant)otherConstant).getValue(); - result = value < otherValue ? -1 : - value == otherValue ? 0 : - 1; + result = Long.compare(longConstant.getValue(), + ((LongConstant)otherConstant).getValue()); } public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) @@ -167,7 +160,7 @@ if (primitiveType != otherPrimitiveType) { - result = primitiveType < otherPrimitiveType ? -1 : 1; + result = Integer.compare(primitiveType, otherPrimitiveType); } else { @@ -196,6 +189,21 @@ result = utf8Constant.getString().compareTo(((Utf8Constant)otherConstant).getString()); } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + DynamicConstant otherDynamicConstant = (DynamicConstant)otherConstant; + + int index = dynamicConstant.getBootstrapMethodAttributeIndex(); + int otherIndex = otherDynamicConstant.getBootstrapMethodAttributeIndex(); + + result = index < otherIndex ? -1 : + index > otherIndex ? 1 : + compare(dynamicConstant.getName(clazz), + dynamicConstant.getType(clazz), + otherDynamicConstant.getName(clazz), + otherDynamicConstant.getType(clazz)); + } + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { InvokeDynamicConstant otherInvokeDynamicConstant = (InvokeDynamicConstant)otherConstant; diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ConstantAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/ConstantAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ConstantAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ConstantAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -141,6 +141,41 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + // Find the bootstrap methods attribute. + AttributesEditor attributesEditor = + new AttributesEditor((ProgramClass)clazz, false); + + BootstrapMethodsAttribute bootstrapMethodsAttribute = + (BootstrapMethodsAttribute)attributesEditor.findAttribute(ClassConstants.ATTR_BootstrapMethods); + + // Add the name and type constant. + clazz.constantPoolEntryAccept(dynamicConstant.u2nameAndTypeIndex, this); + + // Copy the referenced classes. + Clazz[] referencedClasses = dynamicConstant.referencedClasses; + Clazz[] referencedClassesCopy = null; + if (referencedClasses != null) + { + referencedClassesCopy = new Clazz[referencedClasses.length]; + System.arraycopy(referencedClasses, 0, + referencedClassesCopy, 0, + referencedClasses.length); + } + + bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz, + dynamicConstant.getBootstrapMethodAttributeIndex(), + bootstrapMethodsAttributeAdder); + + // Then add the actual invoke dynamic constant. + constantIndex = + constantPoolEditor.addDynamicConstant(bootstrapMethodsAttributeAdder.getBootstrapMethodIndex(), + constantIndex, + referencedClassesCopy); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { // Find the bootstrap methods attribute. diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolEditor.java 2018-05-06 20:26:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -265,9 +265,45 @@ /** - * Finds or creates a InvokeDynamicConstant constant pool entry with the given + * Finds or creates a DynamicConstant constant pool entry with the given * class constant pool entry index and name and type constant pool entry * index. + * @return the constant pool index of the DynamicConstant. + */ + public int addDynamicConstant(int bootstrapMethodIndex, + int nameAndTypeIndex, + Clazz[] referencedClasses) + { + int constantPoolCount = targetClass.u2constantPoolCount; + Constant[] constantPool = targetClass.constantPool; + + // Check if the entry already exists. + for (int index = 1; index < constantPoolCount; index++) + { + Constant constant = constantPool[index]; + + if (constant != null && + constant.getTag() == ClassConstants.CONSTANT_Dynamic) + { + DynamicConstant dynamicConstant = (DynamicConstant)constant; + if (dynamicConstant.u2bootstrapMethodAttributeIndex == bootstrapMethodIndex && + dynamicConstant.u2nameAndTypeIndex == nameAndTypeIndex) + { + return index; + } + } + } + + return addConstant(new DynamicConstant(bootstrapMethodIndex, + nameAndTypeIndex, + referencedClasses)); + } + + + /** + * Finds or creates an InvokeDynamicConstant constant pool entry with the + * given class constant pool entry index and name and type constant pool + * entry index. * @return the constant pool index of the InvokeDynamicConstant. */ public int addInvokeDynamicConstant(int bootstrapMethodIndex, diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolRemapper.java proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolRemapper.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolRemapper.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolRemapper.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -153,6 +153,13 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + dynamicConstant.u2nameAndTypeIndex = + remapConstantIndex(dynamicConstant.u2nameAndTypeIndex); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { invokeDynamicConstant.u2nameAndTypeIndex = @@ -328,6 +335,25 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + nestHostAttribute.u2attributeNameIndex = + remapConstantIndex(nestHostAttribute.u2attributeNameIndex); + nestHostAttribute.u2hostClassIndex = + remapConstantIndex(nestHostAttribute.u2hostClassIndex); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + nestMembersAttribute.u2attributeNameIndex = + remapConstantIndex(nestMembersAttribute.u2attributeNameIndex); + + remapConstantIndexArray(nestMembersAttribute.u2classes, + nestMembersAttribute.u2classesCount); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { moduleAttribute.u2attributeNameIndex = @@ -343,7 +369,8 @@ moduleAttribute.requiresAccept(clazz, this); moduleAttribute.exportsAccept(clazz, this); moduleAttribute.opensAccept(clazz, this); - remapConstantIndexArray(moduleAttribute.u2uses, moduleAttribute.u2usesCount); + remapConstantIndexArray(moduleAttribute.u2uses, + moduleAttribute.u2usesCount); moduleAttribute.providesAccept(clazz, this); } @@ -361,7 +388,9 @@ { modulePackagesAttribute.u2attributeNameIndex = remapConstantIndex(modulePackagesAttribute.u2attributeNameIndex); - remapConstantIndexArray(modulePackagesAttribute.u2packages, modulePackagesAttribute.u2packagesCount); + + remapConstantIndexArray(modulePackagesAttribute.u2packages, + modulePackagesAttribute.u2packagesCount); } @@ -674,7 +703,8 @@ { exportsInfo.u2exportsIndex = remapConstantIndex(exportsInfo.u2exportsIndex); - remapConstantIndexArray(exportsInfo.u2exportsToIndex, exportsInfo.u2exportsToCount); + remapConstantIndexArray(exportsInfo.u2exportsToIndex, + exportsInfo.u2exportsToCount); } @@ -684,7 +714,8 @@ { opensInfo.u2opensIndex = remapConstantIndex(opensInfo.u2opensIndex); - remapConstantIndexArray(opensInfo.u2opensToIndex, opensInfo.u2opensToCount); + remapConstantIndexArray(opensInfo.u2opensToIndex, + opensInfo.u2opensToCount); } @@ -694,7 +725,8 @@ { providesInfo.u2providesIndex = remapConstantIndex(providesInfo.u2providesIndex); - remapConstantIndexArray(providesInfo.u2providesWithIndex, providesInfo.u2providesWithCount); + remapConstantIndexArray(providesInfo.u2providesWithIndex, + providesInfo.u2providesWithCount); } // Implementations for AnnotationVisitor. @@ -735,7 +767,7 @@ { classElementValue.u2elementNameIndex = remapConstantIndex(classElementValue.u2elementNameIndex); - classElementValue.u2classInfoIndex = + classElementValue.u2classInfoIndex = remapConstantIndex(classElementValue.u2classInfoIndex); } @@ -771,8 +803,8 @@ } } - // Small utility methods. + // Small utility methods. /** * Returns the new constant pool index of the entry at the diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolShrinker.java proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolShrinker.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolShrinker.java 2018-02-03 20:18:05.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -142,6 +142,17 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + markAsUsed(dynamicConstant); + + markConstant(clazz, dynamicConstant.u2nameAndTypeIndex); + + // Mark the bootstrap methods attribute. + clazz.attributesAccept(this); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { markAsUsed(invokeDynamicConstant); @@ -253,34 +264,42 @@ public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) { - markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex); - markConstant(clazz, enclosingMethodAttribute.u2classIndex); + markConstant( clazz, enclosingMethodAttribute.u2attributeNameIndex); + markConstant( clazz, enclosingMethodAttribute.u2classIndex); + markOptionalConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); + } - if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) - { - markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); - } + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + markConstant(clazz, nestHostAttribute.u2attributeNameIndex); + markConstant(clazz, nestHostAttribute.u2hostClassIndex); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + markConstant(clazz, nestMembersAttribute.u2attributeNameIndex); + + // Mark the nest member class constants. + nestMembersAttribute.memberClassConstantsAccept(clazz, this); } public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { - markConstant(clazz, moduleAttribute.u2attributeNameIndex); - markConstant(clazz, moduleAttribute.u2moduleNameIndex); + markConstant( clazz, moduleAttribute.u2attributeNameIndex); + markConstant( clazz, moduleAttribute.u2moduleNameIndex); + markOptionalConstant(clazz, moduleAttribute.u2moduleVersionIndex); - if (moduleAttribute.u2moduleVersionIndex != 0) - { - markConstant(clazz, moduleAttribute.u2moduleVersionIndex); - } + // Mark the constant pool entries referenced by the contained info. moduleAttribute.requiresAccept(clazz, this); moduleAttribute.exportsAccept(clazz, this); moduleAttribute.opensAccept(clazz, this); - for (int index = 0; index < moduleAttribute.u2usesCount; index++) - { - markConstant(clazz, moduleAttribute.u2uses[index]); - } + markConstants(clazz, moduleAttribute.u2uses, moduleAttribute.u2usesCount); + // Mark the constant pool entries referenced by the provides info. moduleAttribute.providesAccept(clazz, this); } @@ -296,10 +315,8 @@ { markConstant(clazz, modulePackagesAttribute.u2attributeNameIndex); - for (int index = 0; index < modulePackagesAttribute.u2packagesCount; index++) - { - markConstant(clazz, modulePackagesAttribute.u2packages[index]); - } + // Mark the constant pool entries referenced by the packages info. + modulePackagesAttribute.packagesAccept(clazz, this); } @@ -425,6 +442,7 @@ public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) { + // Mark the constant pool entries referenced by the contained info. innerClassesInfo.innerClassConstantAccept(clazz, this); innerClassesInfo.outerClassConstantAccept(clazz, this); innerClassesInfo.innerNameConstantAccept(clazz, this); @@ -435,10 +453,7 @@ public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { - if (exceptionInfo.u2catchType != 0) - { - markConstant(clazz, exceptionInfo.u2catchType); - } + markOptionalConstant(clazz, exceptionInfo.u2catchType); } @@ -484,10 +499,7 @@ public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo) { - if (parameterInfo.u2nameIndex != 0) - { - markConstant(clazz, parameterInfo.u2nameIndex); - } + markOptionalConstant(clazz, parameterInfo.u2nameIndex); } @@ -513,8 +525,8 @@ public void visitRequiresInfo(Clazz clazz, RequiresInfo requiresInfo) { - markConstant(clazz, requiresInfo.u2requiresIndex); - markConstant(clazz, requiresInfo.u2requiresVersionIndex); + markConstant( clazz, requiresInfo.u2requiresIndex); + markOptionalConstant(clazz, requiresInfo.u2requiresVersionIndex); } @@ -522,12 +534,8 @@ public void visitExportsInfo(Clazz clazz, ExportsInfo exportsInfo) { - markConstant(clazz, exportsInfo.u2exportsIndex); - - for (int index = 0; index < exportsInfo.u2exportsToCount; index++) - { - markConstant(clazz, exportsInfo.u2exportsToIndex[index]); - } + markConstant( clazz, exportsInfo.u2exportsIndex); + markConstants(clazz, exportsInfo.u2exportsToIndex, exportsInfo.u2exportsToCount); } @@ -535,12 +543,8 @@ public void visitOpensInfo(Clazz clazz, OpensInfo opensInfo) { - markConstant(clazz, opensInfo.u2opensIndex); - - for (int index = 0; index < opensInfo.u2opensToCount; index++) - { - markConstant(clazz, opensInfo.u2opensToIndex[index]); - } + markConstant( clazz, opensInfo.u2opensIndex); + markConstants(clazz, opensInfo.u2opensToIndex, opensInfo.u2opensToCount); } @@ -548,12 +552,8 @@ public void visitProvidesInfo(Clazz clazz, ProvidesInfo providesInfo) { - markConstant(clazz, providesInfo.u2providesIndex); - - for (int index = 0; index < providesInfo.u2providesWithCount; index++) - { - markConstant(clazz, providesInfo.u2providesWithIndex[index]); - } + markConstant( clazz, providesInfo.u2providesIndex); + markConstants(clazz, providesInfo.u2providesWithIndex, providesInfo.u2providesWithCount); } @@ -572,44 +572,29 @@ public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) { - if (constantElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, constantElementValue.u2elementNameIndex); - } - - markConstant(clazz, constantElementValue.u2constantValueIndex); + markOptionalConstant(clazz, constantElementValue.u2elementNameIndex); + markConstant( clazz, constantElementValue.u2constantValueIndex); } public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) { - if (enumConstantElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, enumConstantElementValue.u2elementNameIndex); - } - - markConstant(clazz, enumConstantElementValue.u2typeNameIndex); - markConstant(clazz, enumConstantElementValue.u2constantNameIndex); + markOptionalConstant(clazz, enumConstantElementValue.u2elementNameIndex); + markConstant( clazz, enumConstantElementValue.u2typeNameIndex); + markConstant( clazz, enumConstantElementValue.u2constantNameIndex); } public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) { - if (classElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, classElementValue.u2elementNameIndex); - } - - markConstant(clazz, classElementValue.u2classInfoIndex); + markOptionalConstant(clazz, classElementValue.u2elementNameIndex); + markConstant( clazz, classElementValue.u2classInfoIndex); } public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) { - if (annotationElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, annotationElementValue.u2elementNameIndex); - } + markOptionalConstant(clazz, annotationElementValue.u2elementNameIndex); // Mark the constant pool entries referenced by the annotation. annotationElementValue.annotationAccept(clazz, this); @@ -618,10 +603,7 @@ public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) { - if (arrayElementValue.u2elementNameIndex != 0) - { - markConstant(clazz, arrayElementValue.u2elementNameIndex); - } + markOptionalConstant(clazz, arrayElementValue.u2elementNameIndex); // Mark the constant pool entries referenced by the element values. arrayElementValue.elementValuesAccept(clazz, annotation, this); @@ -642,12 +624,40 @@ // Small utility methods. /** - * Marks the given constant pool entry of the given class. This includes - * visiting any referenced objects. + * Marks the specified constant pool entries of the given class. + * This includes visiting any referenced objects. + */ + private void markConstants(Clazz clazz, + int[] constantIndices, + int constantIndicesCount) + { + for (int index = 0; index < constantIndicesCount; index++) + { + markConstant(clazz, constantIndices[index]); + } + } + + + /** + * Marks the specified constant pool entry of the given class, if the index + * is not 0. This includes visiting any referenced objects. + */ + private void markOptionalConstant(Clazz clazz, int constantIndex) + { + if (constantIndex != 0) + { + markConstant(clazz, constantIndex); + } + } + + + /** + * Marks the specified constant pool entry of the given class. + * This includes visiting any referenced objects. */ - private void markConstant(Clazz clazz, int index) + private void markConstant(Clazz clazz, int constantIndex) { - clazz.constantPoolEntryAccept(index, this); + clazz.constantPoolEntryAccept(constantIndex, this); } diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolSorter.java proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolSorter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ConstantPoolSorter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ConstantPoolSorter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ElementValueAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/ElementValueAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ElementValueAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ElementValueAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ElementValuesEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/ElementValuesEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ElementValuesEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ElementValuesEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionInfoAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionInfoAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionInfoAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionInfoAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionInfoEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionInfoEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionInfoEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionInfoEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionsAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionsAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ExceptionsAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ExceptionsAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InnerClassesAccessFixer.java proguard-6.2.0/core/src/proguard/classfile/editor/InnerClassesAccessFixer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InnerClassesAccessFixer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InnerClassesAccessFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InnerClassesAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/InnerClassesAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InnerClassesAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InnerClassesAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InstructionAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/InstructionAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InstructionAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InstructionAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InstructionSequenceBuilder.java proguard-6.2.0/core/src/proguard/classfile/editor/InstructionSequenceBuilder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InstructionSequenceBuilder.java 2018-01-28 00:14:39.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InstructionSequenceBuilder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -351,6 +351,11 @@ return ldc_(constantPoolEditor.addStringConstant(string, referencedClass, referencedMember)); } + public InstructionSequenceBuilder ldc(Clazz clazz) + { + return ldc(clazz.getName(), clazz); + } + public InstructionSequenceBuilder ldc(String className, Clazz referencedClass) { return ldc_(constantPoolEditor.addClassConstant(className, referencedClass)); diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InstructionWriter.java proguard-6.2.0/core/src/proguard/classfile/editor/InstructionWriter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InstructionWriter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InstructionWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InterfaceAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/InterfaceAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InterfaceAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InterfaceAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InterfaceDeleter.java proguard-6.2.0/core/src/proguard/classfile/editor/InterfaceDeleter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InterfaceDeleter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InterfaceDeleter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InterfacesEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/InterfacesEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InterfacesEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InterfacesEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/InterfaceSorter.java proguard-6.2.0/core/src/proguard/classfile/editor/InterfaceSorter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/InterfaceSorter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/InterfaceSorter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LineNumberInfoAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/LineNumberInfoAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LineNumberInfoAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LineNumberInfoAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LineNumberTableAttributeTrimmer.java proguard-6.2.0/core/src/proguard/classfile/editor/LineNumberTableAttributeTrimmer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LineNumberTableAttributeTrimmer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LineNumberTableAttributeTrimmer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableInfoAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableInfoAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableInfoAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableInfoAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/MemberAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/MemberAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/MemberAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/MemberAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,10 +22,14 @@ import proguard.classfile.*; import proguard.classfile.attribute.Attribute; +import proguard.classfile.constant.*; +import proguard.classfile.io.*; import proguard.classfile.util.SimplifiedVisitor; -import proguard.classfile.visitor.MemberVisitor; +import proguard.classfile.visitor.*; import proguard.util.*; +import java.io.*; + /** * This MemberVisitor copies all class members that it visits to the given * target class. Their visitor info is set to the class members from which they @@ -315,4 +319,83 @@ ClassConstants.METHOD_NAME_INIT : name + ClassConstants.SPECIAL_MEMBER_SEPARATOR + Long.toHexString(Math.abs((descriptor).hashCode())); } + + + /** + * This main method illustrates and tests the class, by reading an input + * class file and copying its class members into a new class that it + * writes to an output class file. + */ + public static void main(String[] args) + { + String inputClassFileName = args[0]; + String outputClassFileName = args[1]; + + try + { + DataInputStream dataInputStream = + new DataInputStream( + new FileInputStream(inputClassFileName)); + + try + { + // Read the input class. + ProgramClass inputProgramClass = + new ProgramClass(); + + inputProgramClass.accept( + new ProgramClassReader(dataInputStream)); + + // Create an empty output class. + ProgramClass outputProgramClass = + new ProgramClass(inputProgramClass.u4version, + 1, + new Constant[1], + inputProgramClass.u2accessFlags, + 0, + 0); + + ConstantPoolEditor constantPoolEditor = + new ConstantPoolEditor(outputProgramClass); + + outputProgramClass.u2thisClass = + constantPoolEditor.addClassConstant(inputProgramClass.getName()+"Copy", null); + + outputProgramClass.u2superClass = + constantPoolEditor.addClassConstant(ClassConstants.NAME_JAVA_LANG_OBJECT, null); + + // Copy over the class members. + MemberAdder memberAdder = + new MemberAdder(outputProgramClass); + + inputProgramClass.fieldsAccept(memberAdder); + inputProgramClass.methodsAccept(memberAdder); + + //outputProgramClass.accept(new ClassPrinter()); + + // Write out the output class. + DataOutputStream dataOutputStream = + new DataOutputStream( + new FileOutputStream(outputClassFileName)); + + try + { + outputProgramClass.accept( + new ProgramClassWriter(dataOutputStream)); + } + finally + { + dataOutputStream.close(); + } + } + finally + { + dataInputStream.close(); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/MemberReferenceFixer.java proguard-6.2.0/core/src/proguard/classfile/editor/MemberReferenceFixer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/MemberReferenceFixer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/MemberReferenceFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -48,6 +48,8 @@ private static final boolean DEBUG = false; + private final boolean android; + private final StackSizeUpdater stackSizeUpdater = new StackSizeUpdater(); // Parameter for the visitor methods. @@ -58,6 +60,18 @@ private boolean stackSizesMayHaveChanged; + /** + * Creates a new MemberReferenceFixer. + * + * @param android specifies whether the target is Android. This has subtle + * implications when fixing enum annotations. + */ + public MemberReferenceFixer(boolean android) + { + this.android = android; + } + + // Implementations for ClassVisitor. public void visitProgramClass(ProgramClass programClass) @@ -368,6 +382,30 @@ public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) { fixElementValue(clazz, annotation, enumConstantElementValue); + + // The Java VM expects the original enum constant name, i.e. the + // name string stored in the enum constant. + // The Android tools (dx, D8,...) expect the updated enum constant + // name, i.e. the name of the static field in the enum class. + if (android) + { + // Do we know the referenced enum field? + Member referencedField = enumConstantElementValue.referencedField; + if (referencedField != null) + { + Clazz referencedClass = enumConstantElementValue.referencedClasses[0]; + + // Does it have a new name? + String newName = referencedField.getName(referencedClass); + + if (!enumConstantElementValue.getConstantName(clazz).equals(newName)) + { + // Update the name index. + enumConstantElementValue.u2constantNameIndex = + new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(newName); + } + } + } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/MemberRemover.java proguard-6.2.0/core/src/proguard/classfile/editor/MemberRemover.java --- proguard-6.0.3/core/src/proguard/classfile/editor/MemberRemover.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/MemberRemover.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/MethodInvocationFixer.java proguard-6.2.0/core/src/proguard/classfile/editor/MethodInvocationFixer.java --- proguard-6.0.3/core/src/proguard/classfile/editor/MethodInvocationFixer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/MethodInvocationFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/NameAndTypeShrinker.java proguard-6.2.0/core/src/proguard/classfile/editor/NameAndTypeShrinker.java --- proguard-6.0.3/core/src/proguard/classfile/editor/NameAndTypeShrinker.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/NameAndTypeShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/NamedAttributeDeleter.java proguard-6.2.0/core/src/proguard/classfile/editor/NamedAttributeDeleter.java --- proguard-6.0.3/core/src/proguard/classfile/editor/NamedAttributeDeleter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/NamedAttributeDeleter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/NestMemberAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/NestMemberAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/NestMemberAdder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/NestMemberAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.editor; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; +import proguard.util.ArrayUtil; + +/** + * This ConstantVisitor and ClassVisitor adds the class constants or the + * classes that it visits to the given target nest member attribute. + */ +public class NestMemberAdder +extends SimplifiedVisitor +implements ConstantVisitor, + ClassVisitor + +{ + private final ConstantPoolEditor constantPoolEditor; + private final NestMembersAttribute targetNestMembersAttribute; + + + /** + * Creates a new NestMemberAdder that will add classes to the + * given target nest members attribute. + */ + public NestMemberAdder(ProgramClass targetClass, + NestMembersAttribute targetNestMembersAttribute) + { + this.constantPoolEditor = new ConstantPoolEditor(targetClass); + this.targetNestMembersAttribute = targetNestMembersAttribute; + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + targetNestMembersAttribute.u2classes = + ArrayUtil.add(targetNestMembersAttribute.u2classes, + targetNestMembersAttribute.u2classesCount++, + constantPoolEditor.addClassConstant(classConstant.getName(clazz), + classConstant.referencedClass)); + } + + + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) + { + targetNestMembersAttribute.u2classes = + ArrayUtil.add(targetNestMembersAttribute.u2classes, + targetNestMembersAttribute.u2classesCount++, + constantPoolEditor.addClassConstant(clazz)); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -49,8 +49,44 @@ */ public void addAnnotation(int parameterIndex, Annotation annotation) { - ArrayUtil.add(targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex], - targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex]++, - annotation); + targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex] = + ArrayUtil.add(targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex], + targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex]++, + annotation); + } + + /** + * Deletes a given annotation from the annotations attribute. + */ + public void deleteAnnotation(int parameterIndex, Annotation annotation) + { + int index = findAnnotationIndex(annotation, + targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex], + targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex]); + deleteAnnotation(parameterIndex, index); + } + + /** + * Deletes the annotation at the given index from the annotations attribute. + */ + public void deleteAnnotation(int parameterIndex, int annotationIndex) + { + ArrayUtil.remove(targetParameterAnnotationsAttribute.parameterAnnotations[parameterIndex], + targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex], + annotationIndex); + targetParameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex]--; + } + + private int findAnnotationIndex(Annotation annotation, Annotation[] annotations, int annotationCount) + { + for (int index = 0; index < annotationCount; index++) + { + if (annotation == annotations[index]) + { + return index; + } + + } + return -1; } } \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/ParameterInfoAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/ParameterInfoAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/ParameterInfoAdder.java 2018-02-04 10:06:50.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/ParameterInfoAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/SimplifiedClassEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/SimplifiedClassEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/SimplifiedClassEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/SimplifiedClassEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/StackSizeUpdater.java proguard-6.2.0/core/src/proguard/classfile/editor/StackSizeUpdater.java --- proguard-6.0.3/core/src/proguard/classfile/editor/StackSizeUpdater.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/StackSizeUpdater.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/SubclassAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/SubclassAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/SubclassAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/SubclassAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/SubclassToAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/SubclassToAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/SubclassToAdder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/SubclassToAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/TargetInfoCopier.java proguard-6.2.0/core/src/proguard/classfile/editor/TargetInfoCopier.java --- proguard-6.0.3/core/src/proguard/classfile/editor/TargetInfoCopier.java 2018-02-13 20:03:16.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/TargetInfoCopier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -84,7 +84,7 @@ public void visitEmptyTargetInfo(Clazz clazz, Member member, TypeAnnotation typeAnnotation, EmptyTargetInfo emptyTargetInfo) { targetTypeAnnotation.targetInfo = - new EmptyTargetInfo(); + new EmptyTargetInfo(emptyTargetInfo.u1targetType); } diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/TypeAnnotationAdder.java proguard-6.2.0/core/src/proguard/classfile/editor/TypeAnnotationAdder.java --- proguard-6.0.3/core/src/proguard/classfile/editor/TypeAnnotationAdder.java 2018-02-13 20:14:29.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/TypeAnnotationAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/Utf8Shrinker.java proguard-6.2.0/core/src/proguard/classfile/editor/Utf8Shrinker.java --- proguard-6.0.3/core/src/proguard/classfile/editor/Utf8Shrinker.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/Utf8Shrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -24,6 +24,7 @@ import proguard.classfile.attribute.*; import proguard.classfile.attribute.annotation.*; import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.module.*; import proguard.classfile.attribute.preverification.*; import proguard.classfile.attribute.visitor.*; import proguard.classfile.constant.*; @@ -172,7 +173,34 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + markCpUtf8Entry(clazz, nestHostAttribute.u2attributeNameIndex); + } + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + markCpUtf8Entry(clazz, nestMembersAttribute.u2attributeNameIndex); + } + + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) + { + markCpUtf8Entry(clazz, moduleAttribute.u2attributeNameIndex); + } + + + public void visitModuleMainClassAttribute(Clazz clazz, ModuleMainClassAttribute moduleMainClassAttribute) + { + markCpUtf8Entry(clazz, moduleMainClassAttribute.u2attributeNameIndex); + } + + + public void visitModulePackagesAttribute(Clazz clazz, ModulePackagesAttribute modulePackagesAttribute) + { + markCpUtf8Entry(clazz, modulePackagesAttribute.u2attributeNameIndex); + } public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/VariableCleaner.java proguard-6.2.0/core/src/proguard/classfile/editor/VariableCleaner.java --- proguard-6.0.3/core/src/proguard/classfile/editor/VariableCleaner.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/VariableCleaner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -38,8 +38,10 @@ extends SimplifiedVisitor implements AttributeVisitor { - private boolean deleteLocalVariableTableAttribute; - private boolean deleteLocalVariableTypeTableAttribute; + private LocalVariableTableAttribute localVariableTableAttribute; + private LocalVariableTypeTableAttribute localVariableTypeTableAttribute; + private boolean deleteLocalVariableTableAttribute; + private boolean deleteLocalVariableTypeTableAttribute; // Implementations for AttributeVisitor. @@ -49,12 +51,28 @@ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { + localVariableTableAttribute = null; + localVariableTypeTableAttribute = null; deleteLocalVariableTableAttribute = false; deleteLocalVariableTypeTableAttribute = false; // Trim the local variable table and the local variable type table. codeAttribute.attributesAccept(clazz, method, this); + // Finally, still trim the code blocks of the local variable types, + // based on the code blocks of the local variables, if we have found + // both. The local variable type table may contain fewer entries, + // but the JVM preverifier complains if variables and corresponding + // variable types are inconsistent. + if (localVariableTableAttribute != null && + localVariableTypeTableAttribute != null) + { + trimLocalVariableTypes(localVariableTableAttribute.localVariableTable, + localVariableTableAttribute.u2localVariableTableLength, + localVariableTypeTableAttribute.localVariableTypeTable, + localVariableTypeTableAttribute.u2localVariableTypeTableLength); + } + // Delete the local variable table if it ended up empty. if (deleteLocalVariableTableAttribute) { @@ -99,18 +117,21 @@ { deleteLocalVariableTableAttribute = true; } + + // We still need to remember the attribute. + this.localVariableTableAttribute = localVariableTableAttribute; } public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) { - // Clean up local variables that aren't used. + // Clean up local variable types that aren't used. localVariableTypeTableAttribute.u2localVariableTypeTableLength = removeUnusedLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, localVariableTypeTableAttribute.u2localVariableTypeTableLength, codeAttribute.u2maxLocals); - // Trim the code blocks of the local variables. + // Trim the code blocks of the local variable types. trimLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, localVariableTypeTableAttribute.u2localVariableTypeTableLength, codeAttribute.u2maxLocals); @@ -120,6 +141,9 @@ { deleteLocalVariableTypeTableAttribute = true; } + + // We still need to remember the attribute. + this.localVariableTypeTableAttribute = localVariableTypeTableAttribute; } @@ -235,13 +259,13 @@ int[] startPCs = createMaxArray(maxLocals); - // Trim the local variable entries, starting at the last one. + // Trim the local variable type entries, starting at the last one. for (int index = localVariableTypeInfoCount-1; index >= 0; index--) { LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; - // Make sure the variable's code block doesn't overlap with the - // next one for the same variable. + // Make sure the variable type's code block doesn't overlap with + // the next one for the same variable. int maxLength = startPCs[localVariableTypeInfo.u2index] - localVariableTypeInfo.u2startPC; @@ -254,6 +278,40 @@ } } + + /** + * Trims the code blocks of the given list of local variable types, based + * on the given list of local variables. + */ + private void trimLocalVariableTypes(LocalVariableInfo[] localVariableInfos, + int localVariableInfoCount, + LocalVariableTypeInfo[] localVariableTypeInfos, + int localVariableTypeInfoCount) + { + int typeIndex = 0; + + // Go over the sorted list of local variables. + for (int index = 0; + index < localVariableInfoCount && + typeIndex < localVariableTypeInfoCount; + index++) + { + LocalVariableInfo localVariableInfo = localVariableInfos[index]; + LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[typeIndex]; + + // Do we have a corresponding variable type? + if (localVariableTypeInfo.u2index == localVariableInfo.u2index && + localVariableTypeInfo.u2startPC == localVariableInfo.u2startPC) + { + // Just copy the length. + localVariableTypeInfo.u2length = localVariableInfo.u2length; + + // Continue with the next local variable type. + typeIndex++; + } + } + } + /** * Creates an integer array of the given length, initialized with diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/VariableEditor.java proguard-6.2.0/core/src/proguard/classfile/editor/VariableEditor.java --- proguard-6.0.3/core/src/proguard/classfile/editor/VariableEditor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/VariableEditor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/VariableRemapper.java proguard-6.2.0/core/src/proguard/classfile/editor/VariableRemapper.java --- proguard-6.0.3/core/src/proguard/classfile/editor/VariableRemapper.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/VariableRemapper.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/editor/VariableSizeUpdater.java proguard-6.2.0/core/src/proguard/classfile/editor/VariableSizeUpdater.java --- proguard-6.0.3/core/src/proguard/classfile/editor/VariableSizeUpdater.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/editor/VariableSizeUpdater.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/Field.java proguard-6.2.0/core/src/proguard/classfile/Field.java --- proguard-6.0.3/core/src/proguard/classfile/Field.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/Field.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/BranchInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/BranchInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/BranchInstruction.java 2018-01-24 21:44:58.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/BranchInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/ConstantInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/ConstantInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/ConstantInstruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/ConstantInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -240,6 +240,12 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + clazz.constantPoolEntryAccept(dynamicConstant.u2nameAndTypeIndex, this); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this); diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/InstructionConstants.java proguard-6.2.0/core/src/proguard/classfile/instruction/InstructionConstants.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/InstructionConstants.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/InstructionConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/InstructionFactory.java proguard-6.2.0/core/src/proguard/classfile/instruction/InstructionFactory.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/InstructionFactory.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/InstructionFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -29,12 +29,10 @@ { /** * Creates a new Instruction from the data in the byte array, starting - * at the given index. + * at the given offset. */ public static Instruction create(byte[] code, int offset) { - Instruction instruction; - int index = offset; byte opcode = code[index++]; @@ -45,6 +43,34 @@ wide = true; } + Instruction instruction = create(opcode, wide); + + instruction.opcode = opcode; + + instruction.readInfo(code, index); + + return instruction; + } + + + /** + * Creates a new Instruction corresponding to the given opcode. + */ + public static Instruction create(byte opcode) + { + Instruction instruction = create(opcode, false); + + instruction.opcode = opcode; + + return instruction; + } + + + /** + * Creates a new Instruction corresponding to the given opcode. + */ + private static Instruction create(byte opcode, boolean wide) + { switch (opcode) { // Simple instructions. @@ -165,8 +191,7 @@ case InstructionConstants.OP_MONITORENTER: case InstructionConstants.OP_MONITOREXIT: - instruction = new SimpleInstruction(); - break; + return new SimpleInstruction(); // Instructions with a contant pool index. case InstructionConstants.OP_LDC: @@ -189,8 +214,7 @@ case InstructionConstants.OP_CHECKCAST: case InstructionConstants.OP_INSTANCEOF: case InstructionConstants.OP_MULTIANEWARRAY: - instruction = new ConstantInstruction(); - break; + return new ConstantInstruction(); // Instructions with a local variable index. case InstructionConstants.OP_ILOAD: @@ -248,8 +272,7 @@ case InstructionConstants.OP_IINC: case InstructionConstants.OP_RET: - instruction = new VariableInstruction(wide); - break; + return new VariableInstruction(wide); // Instructions with a branch offset operand. case InstructionConstants.OP_IFEQ: @@ -274,27 +297,18 @@ case InstructionConstants.OP_GOTO_W: case InstructionConstants.OP_JSR_W: - instruction = new BranchInstruction(); - break; + return new BranchInstruction(); // The tableswitch instruction. case InstructionConstants.OP_TABLESWITCH: - instruction = new TableSwitchInstruction(); - break; + return new TableSwitchInstruction(); // The lookupswitch instruction. case InstructionConstants.OP_LOOKUPSWITCH: - instruction = new LookUpSwitchInstruction(); - break; + return new LookUpSwitchInstruction(); default: - throw new IllegalArgumentException("Unknown instruction opcode ["+opcode+"] at offset "+offset); + throw new IllegalArgumentException("Unknown instruction opcode ["+opcode+"]"); } - - instruction.opcode = opcode; - - instruction.readInfo(code, index); - - return instruction; } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/Instruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/Instruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/Instruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/Instruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -879,6 +879,16 @@ /** + * Returns the actual opcode of this instruction, i.e. the opcode that is + * stored in the bytecode. + */ + public byte actualOpcode() + { + return opcode; + } + + + /** * Shrinks this instruction to its shortest possible form. * @return this instruction. */ @@ -907,7 +917,7 @@ } // Write the opcode. - code[offset++] = opcode; + code[offset++] = actualOpcode(); // Write any additional arguments. writeInfo(code, offset); diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/InstructionUtil.java proguard-6.2.0/core/src/proguard/classfile/instruction/InstructionUtil.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/InstructionUtil.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/InstructionUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/LookUpSwitchInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/LookUpSwitchInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/LookUpSwitchInstruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/LookUpSwitchInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/SimpleInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/SimpleInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/SimpleInstruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/SimpleInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/SwitchInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/SwitchInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/SwitchInstruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/SwitchInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/TableSwitchInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/TableSwitchInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/TableSwitchInstruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/TableSwitchInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/VariableInstruction.java proguard-6.2.0/core/src/proguard/classfile/instruction/VariableInstruction.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/VariableInstruction.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/VariableInstruction.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/InstructionConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/InstructionConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/InstructionConstantVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/InstructionConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/InstructionCounter.java proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/InstructionCounter.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/InstructionCounter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/InstructionCounter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/InstructionVisitor.java proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/InstructionVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/InstructionVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/InstructionVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/io/LibraryClassReader.java proguard-6.2.0/core/src/proguard/classfile/io/LibraryClassReader.java --- proguard-6.0.3/core/src/proguard/classfile/io/LibraryClassReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/io/LibraryClassReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -286,6 +286,12 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + dataInput.skipBytes(4); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { dataInput.skipBytes(4); @@ -369,6 +375,7 @@ case ClassConstants.CONSTANT_Double: return new DoubleConstant(); case ClassConstants.CONSTANT_String: return new StringConstant(); case ClassConstants.CONSTANT_Utf8: return new Utf8Constant(); + case ClassConstants.CONSTANT_Dynamic: return new DynamicConstant(); case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant(); case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant(); case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant(); diff -Nru proguard-6.0.3/core/src/proguard/classfile/io/ProgramClassReader.java proguard-6.2.0/core/src/proguard/classfile/io/ProgramClassReader.java --- proguard-6.0.3/core/src/proguard/classfile/io/ProgramClassReader.java 2018-02-04 10:54:26.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/io/ProgramClassReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -127,12 +127,7 @@ // Read the interfaces. programClass.u2interfacesCount = dataInput.readUnsignedShort(); - - programClass.u2interfaces = new int[programClass.u2interfacesCount]; - for (int index = 0; index < programClass.u2interfacesCount; index++) - { - programClass.u2interfaces[index] = dataInput.readUnsignedShort(); - } + programClass.u2interfaces = readUnsignedShorts(programClass.u2interfacesCount); // Read the fields. programClass.u2fieldsCount = dataInput.readUnsignedShort(); @@ -367,6 +362,13 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + dynamicConstant.u2bootstrapMethodAttributeIndex = dataInput.readUnsignedShort(); + dynamicConstant.u2nameAndTypeIndex = dataInput.readUnsignedShort(); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { invokeDynamicConstant.u2bootstrapMethodAttributeIndex = dataInput.readUnsignedShort(); @@ -479,6 +481,20 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + nestHostAttribute.u2hostClassIndex = dataInput.readUnsignedShort(); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + // Read the nest host classes. + nestMembersAttribute.u2classesCount = dataInput.readUnsignedShort(); + nestMembersAttribute.u2classes = readUnsignedShorts(nestMembersAttribute.u2classesCount); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { moduleAttribute.u2moduleNameIndex = dataInput.readUnsignedShort(); @@ -519,13 +535,8 @@ } // Read the uses. - moduleAttribute.u2usesCount = dataInput.readUnsignedShort(); - - moduleAttribute.u2uses = new int[moduleAttribute.u2usesCount]; - for (int index = 0; index < moduleAttribute.u2usesCount; index++) - { - moduleAttribute.u2uses[index] = dataInput.readUnsignedShort(); - } + moduleAttribute.u2usesCount = dataInput.readUnsignedShort(); + moduleAttribute.u2uses = readUnsignedShorts(moduleAttribute.u2usesCount); // Read the provides. moduleAttribute.u2providesCount = dataInput.readUnsignedShort(); @@ -550,11 +561,7 @@ { // Read the packages. modulePackagesAttribute.u2packagesCount = dataInput.readUnsignedShort(); - - modulePackagesAttribute.u2packages = new int[modulePackagesAttribute.u2packagesCount]; - for (int index = 0; index < modulePackagesAttribute.u2packagesCount; index++) { - modulePackagesAttribute.u2packages[index] = dataInput.readUnsignedShort(); - } + modulePackagesAttribute.u2packages = readUnsignedShorts(modulePackagesAttribute.u2packagesCount); } @@ -601,12 +608,7 @@ { // Read the exceptions. exceptionsAttribute.u2exceptionIndexTableLength = dataInput.readUnsignedShort(); - - exceptionsAttribute.u2exceptionIndexTable = new int[exceptionsAttribute.u2exceptionIndexTableLength]; - for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++) - { - exceptionsAttribute.u2exceptionIndexTable[index] = dataInput.readUnsignedShort(); - } + exceptionsAttribute.u2exceptionIndexTable = readUnsignedShorts(exceptionsAttribute.u2exceptionIndexTableLength); } @@ -741,22 +743,10 @@ { // Read the parameter annotations. parameterAnnotationsAttribute.u1parametersCount = dataInput.readUnsignedByte(); - - // The java compilers of JDK 1.5, JDK 1.6, and Eclipse all count the - // number of parameters of constructors of non-static inner classes - // incorrectly. Fix it right here. - int parameterStart = 0; - if (method.getName(clazz).equals(ClassConstants.METHOD_NAME_INIT)) - { - int realParametersCount = ClassUtil.internalMethodParameterCount(method.getDescriptor(clazz)); - parameterStart = realParametersCount - parameterAnnotationsAttribute.u1parametersCount; - parameterAnnotationsAttribute.u1parametersCount = realParametersCount; - } - parameterAnnotationsAttribute.u2parameterAnnotationsCount = new int[parameterAnnotationsAttribute.u1parametersCount]; parameterAnnotationsAttribute.parameterAnnotations = new Annotation[parameterAnnotationsAttribute.u1parametersCount][]; - for (int parameterIndex = parameterStart; parameterIndex < parameterAnnotationsAttribute.u1parametersCount; parameterIndex++) + for (int parameterIndex = 0; parameterIndex < parameterAnnotationsAttribute.u1parametersCount; parameterIndex++) { // Read the parameter annotations of the given parameter. int u2annotationsCount = dataInput.readUnsignedShort(); @@ -808,11 +798,7 @@ // Read the bootstrap method arguments. bootstrapMethodInfo.u2methodArgumentCount = dataInput.readUnsignedShort(); - bootstrapMethodInfo.u2methodArguments = new int[bootstrapMethodInfo.u2methodArgumentCount]; - for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++) - { - bootstrapMethodInfo.u2methodArguments[index] = dataInput.readUnsignedShort(); - } + bootstrapMethodInfo.u2methodArguments = readUnsignedShorts(bootstrapMethodInfo.u2methodArgumentCount); } @@ -991,12 +977,7 @@ // Read the targets. exportsInfo.u2exportsToCount = dataInput.readUnsignedShort(); - - exportsInfo.u2exportsToIndex = new int[exportsInfo.u2exportsToCount]; - for (int index = 0; index < exportsInfo.u2exportsToCount; index++) - { - exportsInfo.u2exportsToIndex[index] = dataInput.readUnsignedShort(); - } + exportsInfo.u2exportsToIndex = readUnsignedShorts(exportsInfo.u2exportsToCount); } @@ -1009,12 +990,7 @@ // Read the targets. opensInfo.u2opensToCount = dataInput.readUnsignedShort(); - - opensInfo.u2opensToIndex = new int[opensInfo.u2opensToCount]; - for (int index = 0; index < opensInfo.u2opensToCount; index++) - { - opensInfo.u2opensToIndex[index] = dataInput.readUnsignedShort(); - } + opensInfo.u2opensToIndex = readUnsignedShorts(opensInfo.u2opensToCount); } @@ -1024,14 +1000,9 @@ { providesInfo.u2providesIndex = dataInput.readUnsignedShort(); - // Read the withs. + // Read the provides withs. providesInfo.u2providesWithCount = dataInput.readUnsignedShort(); - - providesInfo.u2providesWithIndex = new int[providesInfo.u2providesWithCount]; - for (int index = 0; index < providesInfo.u2providesWithCount; index++) - { - providesInfo.u2providesWithIndex[index] = dataInput.readUnsignedShort(); - } + providesInfo.u2providesWithIndex = readUnsignedShorts(providesInfo.u2providesWithCount); } @@ -1233,6 +1204,7 @@ case ClassConstants.CONSTANT_PrimitiveArray: return new PrimitiveArrayConstant(); case ClassConstants.CONSTANT_String: return new StringConstant(); case ClassConstants.CONSTANT_Utf8: return new Utf8Constant(); + case ClassConstants.CONSTANT_Dynamic: return new DynamicConstant(); case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant(); case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant(); case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant(); @@ -1256,33 +1228,35 @@ String attributeName = clazz.getString(u2attributeNameIndex); Attribute attribute = - attributeName.equals(ClassConstants.ATTR_BootstrapMethods) ? (Attribute)new BootstrapMethodsAttribute(): - attributeName.equals(ClassConstants.ATTR_SourceFile) ? (Attribute)new SourceFileAttribute(): - attributeName.equals(ClassConstants.ATTR_SourceDir) ? (Attribute)new SourceDirAttribute(): - attributeName.equals(ClassConstants.ATTR_InnerClasses) ? (Attribute)new InnerClassesAttribute(): - attributeName.equals(ClassConstants.ATTR_EnclosingMethod) ? (Attribute)new EnclosingMethodAttribute(): - attributeName.equals(ClassConstants.ATTR_Deprecated) ? (Attribute)new DeprecatedAttribute(): - attributeName.equals(ClassConstants.ATTR_Synthetic) ? (Attribute)new SyntheticAttribute(): - attributeName.equals(ClassConstants.ATTR_Signature) ? (Attribute)new SignatureAttribute(): - attributeName.equals(ClassConstants.ATTR_ConstantValue) ? (Attribute)new ConstantValueAttribute(): - attributeName.equals(ClassConstants.ATTR_MethodParameters) ? (Attribute)new MethodParametersAttribute(): - attributeName.equals(ClassConstants.ATTR_Exceptions) ? (Attribute)new ExceptionsAttribute(): - attributeName.equals(ClassConstants.ATTR_Code) ? (Attribute)new CodeAttribute(): - attributeName.equals(ClassConstants.ATTR_StackMap) ? (Attribute)new StackMapAttribute(): - attributeName.equals(ClassConstants.ATTR_StackMapTable) ? (Attribute)new StackMapTableAttribute(): - attributeName.equals(ClassConstants.ATTR_LineNumberTable) ? (Attribute)new LineNumberTableAttribute(): - attributeName.equals(ClassConstants.ATTR_LocalVariableTable) ? (Attribute)new LocalVariableTableAttribute(): - attributeName.equals(ClassConstants.ATTR_LocalVariableTypeTable) ? (Attribute)new LocalVariableTypeTableAttribute(): - attributeName.equals(ClassConstants.ATTR_RuntimeVisibleAnnotations) ? (Attribute)new RuntimeVisibleAnnotationsAttribute(): - attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleAnnotations) ? (Attribute)new RuntimeInvisibleAnnotationsAttribute(): - attributeName.equals(ClassConstants.ATTR_RuntimeVisibleParameterAnnotations) ? (Attribute)new RuntimeVisibleParameterAnnotationsAttribute(): - attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleParameterAnnotations) ? (Attribute)new RuntimeInvisibleParameterAnnotationsAttribute(): - attributeName.equals(ClassConstants.ATTR_RuntimeVisibleTypeAnnotations) ? (Attribute)new RuntimeVisibleTypeAnnotationsAttribute(): - attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleTypeAnnotations) ? (Attribute)new RuntimeInvisibleTypeAnnotationsAttribute(): - attributeName.equals(ClassConstants.ATTR_AnnotationDefault) ? (Attribute)new AnnotationDefaultAttribute(): - attributeName.equals(ClassConstants.ATTR_Module) ? (Attribute)new ModuleAttribute(): - attributeName.equals(ClassConstants.ATTR_ModuleMainClass) ? (Attribute)new ModuleMainClassAttribute(): - attributeName.equals(ClassConstants.ATTR_ModulePackages) ? (Attribute)new ModulePackagesAttribute(): + attributeName.equals(ClassConstants.ATTR_BootstrapMethods) ? (Attribute)new BootstrapMethodsAttribute() : + attributeName.equals(ClassConstants.ATTR_SourceFile) ? (Attribute)new SourceFileAttribute() : + attributeName.equals(ClassConstants.ATTR_SourceDir) ? (Attribute)new SourceDirAttribute() : + attributeName.equals(ClassConstants.ATTR_InnerClasses) ? (Attribute)new InnerClassesAttribute() : + attributeName.equals(ClassConstants.ATTR_EnclosingMethod) ? (Attribute)new EnclosingMethodAttribute() : + attributeName.equals(ClassConstants.ATTR_NestHost) ? (Attribute)new NestHostAttribute() : + attributeName.equals(ClassConstants.ATTR_NestMembers) ? (Attribute)new NestMembersAttribute() : + attributeName.equals(ClassConstants.ATTR_Deprecated) ? (Attribute)new DeprecatedAttribute() : + attributeName.equals(ClassConstants.ATTR_Synthetic) ? (Attribute)new SyntheticAttribute() : + attributeName.equals(ClassConstants.ATTR_Signature) ? (Attribute)new SignatureAttribute() : + attributeName.equals(ClassConstants.ATTR_ConstantValue) ? (Attribute)new ConstantValueAttribute() : + attributeName.equals(ClassConstants.ATTR_MethodParameters) ? (Attribute)new MethodParametersAttribute() : + attributeName.equals(ClassConstants.ATTR_Exceptions) ? (Attribute)new ExceptionsAttribute() : + attributeName.equals(ClassConstants.ATTR_Code) ? (Attribute)new CodeAttribute() : + attributeName.equals(ClassConstants.ATTR_StackMap) ? (Attribute)new StackMapAttribute() : + attributeName.equals(ClassConstants.ATTR_StackMapTable) ? (Attribute)new StackMapTableAttribute() : + attributeName.equals(ClassConstants.ATTR_LineNumberTable) ? (Attribute)new LineNumberTableAttribute() : + attributeName.equals(ClassConstants.ATTR_LocalVariableTable) ? (Attribute)new LocalVariableTableAttribute() : + attributeName.equals(ClassConstants.ATTR_LocalVariableTypeTable) ? (Attribute)new LocalVariableTypeTableAttribute() : + attributeName.equals(ClassConstants.ATTR_RuntimeVisibleAnnotations) ? (Attribute)new RuntimeVisibleAnnotationsAttribute() : + attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleAnnotations) ? (Attribute)new RuntimeInvisibleAnnotationsAttribute() : + attributeName.equals(ClassConstants.ATTR_RuntimeVisibleParameterAnnotations) ? (Attribute)new RuntimeVisibleParameterAnnotationsAttribute() : + attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleParameterAnnotations) ? (Attribute)new RuntimeInvisibleParameterAnnotationsAttribute() : + attributeName.equals(ClassConstants.ATTR_RuntimeVisibleTypeAnnotations) ? (Attribute)new RuntimeVisibleTypeAnnotationsAttribute() : + attributeName.equals(ClassConstants.ATTR_RuntimeInvisibleTypeAnnotations) ? (Attribute)new RuntimeInvisibleTypeAnnotationsAttribute() : + attributeName.equals(ClassConstants.ATTR_AnnotationDefault) ? (Attribute)new AnnotationDefaultAttribute() : + attributeName.equals(ClassConstants.ATTR_Module) ? (Attribute)new ModuleAttribute() : + attributeName.equals(ClassConstants.ATTR_ModuleMainClass) ? (Attribute)new ModuleMainClassAttribute() : + attributeName.equals(ClassConstants.ATTR_ModulePackages) ? (Attribute)new ModulePackagesAttribute() : (Attribute)new UnknownAttribute(u2attributeNameIndex, u4attributeLength); attribute.u2attributeNameIndex = u2attributeNameIndex; @@ -1384,4 +1358,20 @@ default: throw new IllegalArgumentException("Unknown element value tag ["+u1tag+"]"); } } + + + /** + * Reads a list of unsigned shorts of the given size. + */ + private int[] readUnsignedShorts(int size) + { + int[] values = new int[size]; + + for (int index = 0; index < size; index++) + { + values[index] = dataInput.readUnsignedShort(); + } + + return values; + } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/io/ProgramClassWriter.java proguard-6.2.0/core/src/proguard/classfile/io/ProgramClassWriter.java --- proguard-6.0.3/core/src/proguard/classfile/io/ProgramClassWriter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/io/ProgramClassWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -93,12 +93,8 @@ dataOutput.writeUnsignedShort(programClass.u2superClass); // Write the interfaces. - dataOutput.writeUnsignedShort(programClass.u2interfacesCount); - - for (int index = 0; index < programClass.u2interfacesCount; index++) - { - dataOutput.writeUnsignedShort(programClass.u2interfaces[index]); - } + writeUnsignedShorts(programClass.u2interfaces, + programClass.u2interfacesCount); // Write the fields. dataOutput.writeUnsignedShort(programClass.u2fieldsCount); @@ -232,6 +228,13 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + dataOutput.writeUnsignedShort(dynamicConstant.u2bootstrapMethodAttributeIndex); + dataOutput.writeUnsignedShort(dynamicConstant.u2nameAndTypeIndex); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { dataOutput.writeUnsignedShort(invokeDynamicConstant.u2bootstrapMethodAttributeIndex); @@ -435,6 +438,20 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + dataOutput.writeUnsignedShort(nestHostAttribute.u2hostClassIndex); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + // Write the nest host classes. + writeUnsignedShorts(nestMembersAttribute.u2classes, + nestMembersAttribute.u2classesCount); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { dataOutput.writeUnsignedShort(moduleAttribute.u2moduleNameIndex); @@ -457,12 +474,7 @@ moduleAttribute.opensAccept(clazz, this); // Write the uses. - dataOutput.writeUnsignedShort(moduleAttribute.u2usesCount); - - for (int index = 0; index < moduleAttribute.u2usesCount; index++) - { - dataOutput.writeUnsignedShort(moduleAttribute.u2uses[index]); - } + writeUnsignedShorts(moduleAttribute.u2uses, moduleAttribute.u2usesCount); // Write the provides. dataOutput.writeUnsignedShort(moduleAttribute.u2providesCount); @@ -480,12 +492,8 @@ public void visitModulePackagesAttribute(Clazz clazz, ModulePackagesAttribute modulePackagesAttribute) { // Write the packages. - dataOutput.writeUnsignedShort(modulePackagesAttribute.u2packagesCount); - - for (int index = 0; index < modulePackagesAttribute.u2packagesCount; index++) - { - dataOutput.writeUnsignedShort(modulePackagesAttribute.u2packages[index]); - } + writeUnsignedShorts(modulePackagesAttribute.u2packages, + modulePackagesAttribute.u2packagesCount); } @@ -525,12 +533,8 @@ public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) { // Write the exceptions. - dataOutput.writeUnsignedShort(exceptionsAttribute.u2exceptionIndexTableLength); - - for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++) - { - dataOutput.writeUnsignedShort(exceptionsAttribute.u2exceptionIndexTable[index]); - } + writeUnsignedShorts(exceptionsAttribute.u2exceptionIndexTable, + exceptionsAttribute.u2exceptionIndexTableLength); } @@ -616,12 +620,8 @@ dataOutput.writeUnsignedShort(exportsInfo.u2exportsFlags); // Write tthe argets. - dataOutput.writeUnsignedShort(exportsInfo.u2exportsToCount); - - for (int index = 0; index < exportsInfo.u2exportsToCount; index++) - { - dataOutput.writeUnsignedShort(exportsInfo.u2exportsToIndex[index]); - } + writeUnsignedShorts(exportsInfo.u2exportsToIndex, + exportsInfo.u2exportsToCount); } @@ -631,12 +631,8 @@ dataOutput.writeUnsignedShort(opensInfo.u2opensFlags); // Write the targets. - dataOutput.writeUnsignedShort(opensInfo.u2opensToCount); - - for (int index = 0; index < opensInfo.u2opensToCount; index++) - { - dataOutput.writeUnsignedShort(opensInfo.u2opensToIndex[index]); - } + writeUnsignedShorts(opensInfo.u2opensToIndex, + opensInfo.u2opensToCount); } @@ -644,13 +640,9 @@ { dataOutput.writeUnsignedShort(providesInfo.u2providesIndex); - // Write the with. - dataOutput.writeUnsignedShort(providesInfo.u2providesWithCount); - - for (int index = 0; index < providesInfo.u2providesWithCount; index++) - { - dataOutput.writeUnsignedShort(providesInfo.u2providesWithIndex[index]); - } + // Write the provides. + writeUnsignedShorts(providesInfo.u2providesWithIndex, + providesInfo.u2providesWithCount); } @@ -708,12 +700,8 @@ dataOutput.writeUnsignedShort(bootstrapMethodInfo.u2methodHandleIndex); // Write the bootstrap method arguments. - dataOutput.writeUnsignedShort(bootstrapMethodInfo.u2methodArgumentCount); - - for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++) - { - dataOutput.writeUnsignedShort(bootstrapMethodInfo.u2methodArguments[index]); - } + writeUnsignedShorts(bootstrapMethodInfo.u2methodArguments, + bootstrapMethodInfo.u2methodArgumentCount); } @@ -1066,4 +1054,20 @@ arrayElementValue.elementValuesAccept(clazz, annotation, attributeBodyWriter); } } + + + // Small utility methods. + + /** + * Writes the length and the contents of the given list of unsigned shorts. + */ + private void writeUnsignedShorts(int[] array, int size) + { + dataOutput.writeUnsignedShort(size); + + for (int index = 0; index < size; index++) + { + dataOutput.writeUnsignedShort(array[index]); + } + } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/io/RuntimeDataInput.java proguard-6.2.0/core/src/proguard/classfile/io/RuntimeDataInput.java --- proguard-6.0.3/core/src/proguard/classfile/io/RuntimeDataInput.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/io/RuntimeDataInput.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/io/RuntimeDataOutput.java proguard-6.2.0/core/src/proguard/classfile/io/RuntimeDataOutput.java --- proguard-6.0.3/core/src/proguard/classfile/io/RuntimeDataOutput.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/io/RuntimeDataOutput.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/JavaConstants.java proguard-6.2.0/core/src/proguard/classfile/JavaConstants.java --- proguard-6.0.3/core/src/proguard/classfile/JavaConstants.java 2018-03-29 16:35:17.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/JavaConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -45,6 +45,9 @@ 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 CLASS_VERSION_11 = "11"; + public static final String CLASS_VERSION_12 = "12"; + public static final String CLASS_VERSION_13 = "13"; public static final String ACC_PUBLIC = "public"; public static final String ACC_PRIVATE = "private"; diff -Nru proguard-6.0.3/core/src/proguard/classfile/LibraryClass.java proguard-6.2.0/core/src/proguard/classfile/LibraryClass.java --- proguard-6.0.3/core/src/proguard/classfile/LibraryClass.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/LibraryClass.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/LibraryField.java proguard-6.2.0/core/src/proguard/classfile/LibraryField.java --- proguard-6.0.3/core/src/proguard/classfile/LibraryField.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/LibraryField.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/LibraryMember.java proguard-6.2.0/core/src/proguard/classfile/LibraryMember.java --- proguard-6.0.3/core/src/proguard/classfile/LibraryMember.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/LibraryMember.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/LibraryMethod.java proguard-6.2.0/core/src/proguard/classfile/LibraryMethod.java --- proguard-6.0.3/core/src/proguard/classfile/LibraryMethod.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/LibraryMethod.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/Member.java proguard-6.2.0/core/src/proguard/classfile/Member.java --- proguard-6.0.3/core/src/proguard/classfile/Member.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/Member.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/Method.java proguard-6.2.0/core/src/proguard/classfile/Method.java --- proguard-6.0.3/core/src/proguard/classfile/Method.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/Method.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/ProgramClass.java proguard-6.2.0/core/src/proguard/classfile/ProgramClass.java --- proguard-6.0.3/core/src/proguard/classfile/ProgramClass.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/ProgramClass.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/ProgramField.java proguard-6.2.0/core/src/proguard/classfile/ProgramField.java --- proguard-6.0.3/core/src/proguard/classfile/ProgramField.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/ProgramField.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/ProgramMember.java proguard-6.2.0/core/src/proguard/classfile/ProgramMember.java --- proguard-6.0.3/core/src/proguard/classfile/ProgramMember.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/ProgramMember.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/ProgramMethod.java proguard-6.2.0/core/src/proguard/classfile/ProgramMethod.java --- proguard-6.0.3/core/src/proguard/classfile/ProgramMethod.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/ProgramMethod.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/AccessUtil.java proguard-6.2.0/core/src/proguard/classfile/util/AccessUtil.java --- proguard-6.0.3/core/src/proguard/classfile/util/AccessUtil.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/AccessUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/AllParameterVisitor.java proguard-6.2.0/core/src/proguard/classfile/util/AllParameterVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/util/AllParameterVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/AllParameterVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ArrayInitializationMatcher.java proguard-6.2.0/core/src/proguard/classfile/util/ArrayInitializationMatcher.java --- proguard-6.0.3/core/src/proguard/classfile/util/ArrayInitializationMatcher.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ArrayInitializationMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ArrayInitializationReplacer.java proguard-6.2.0/core/src/proguard/classfile/util/ArrayInitializationReplacer.java --- proguard-6.0.3/core/src/proguard/classfile/util/ArrayInitializationReplacer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ArrayInitializationReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ClassReferenceInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/ClassReferenceInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/ClassReferenceInitializer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ClassReferenceInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -180,6 +180,14 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + dynamicConstant.referencedClasses = + findReferencedClasses(clazz, + dynamicConstant.getType(clazz)); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { invokeDynamicConstant.referencedClasses = diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ClassSubHierarchyInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/ClassSubHierarchyInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/ClassSubHierarchyInitializer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ClassSubHierarchyInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ClassUtil.java proguard-6.2.0/core/src/proguard/classfile/util/ClassUtil.java --- proguard-6.0.3/core/src/proguard/classfile/util/ClassUtil.java 2018-03-29 16:34:26.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ClassUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -107,6 +107,9 @@ 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 : + externalClassVersion.equals(JavaConstants.CLASS_VERSION_11) ? ClassConstants.CLASS_VERSION_11 : + externalClassVersion.equals(JavaConstants.CLASS_VERSION_12) ? ClassConstants.CLASS_VERSION_12 : + externalClassVersion.equals(JavaConstants.CLASS_VERSION_13) ? ClassConstants.CLASS_VERSION_13 : 0; } @@ -130,6 +133,9 @@ 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; + case ClassConstants.CLASS_VERSION_11: return JavaConstants.CLASS_VERSION_11; + case ClassConstants.CLASS_VERSION_12: return JavaConstants.CLASS_VERSION_12; + case ClassConstants.CLASS_VERSION_13: return JavaConstants.CLASS_VERSION_13; default: return null; } } @@ -143,14 +149,14 @@ public static void checkVersionNumbers(int internalClassVersion) throws UnsupportedOperationException { if (internalClassVersion < ClassConstants.CLASS_VERSION_1_0 || - internalClassVersion > ClassConstants.CLASS_VERSION_10) + internalClassVersion > ClassConstants.CLASS_VERSION_13) { throw new UnsupportedOperationException("Unsupported version number ["+ internalMajorClassVersion(internalClassVersion)+"."+ internalMinorClassVersion(internalClassVersion)+"] (maximum "+ - ClassConstants.CLASS_VERSION_10_MAJOR+"."+ - ClassConstants.CLASS_VERSION_10_MINOR+", Java "+ - JavaConstants.CLASS_VERSION_10+")"); + ClassConstants.CLASS_VERSION_13_MAJOR+"."+ + ClassConstants.CLASS_VERSION_13_MINOR+", Java "+ + JavaConstants.CLASS_VERSION_13+")"); } } @@ -782,6 +788,174 @@ } + /** + * Returns the parameter number in the given internal method descriptor, + * corresponding to the given variable index. This accounts for long and + * double parameters taking up two spaces, and a non-static method taking + * up an additional entry. The method returns 0 if the index corresponds + * to the 'this' parameter and -1 if the index does not correspond to a + * parameter. + * @param internalMethodDescriptor the internal method descriptor, + * e.g. "(IDI)Z". + * @param accessFlags the access flags of the method, + * e.g. 0. + * @param variableIndex the variable index of the parameter, + * e.g. 4. + * @return the parameter number in the descriptor, + * e.g. 3. + */ + public static int internalMethodParameterNumber(String internalMethodDescriptor, + int accessFlags, + int variableIndex) + { + return internalMethodParameterNumber(internalMethodDescriptor, + (accessFlags & ClassConstants.ACC_STATIC) != 0, + variableIndex); + } + + + /** + * Returns the parameter number in the given internal method descriptor, + * corresponding to the given variable index. This accounts for long and + * double parameters taking up two spaces, and a non-static method taking + * up an additional entry. The method returns 0 if the index corresponds + * to the 'this' parameter and -1 if the index does not correspond to a + * parameter. + * @param internalMethodDescriptor the internal method descriptor, + * e.g. "(IDI)Z". + * @param isStatic specifies whether the method is static, + * e.g. false. + * @param variableIndex the variable index of the parameter, + * e.g. 4. + * @return the parameter number in the descriptor, + * e.g. 3. + */ + public static int internalMethodParameterNumber(String internalMethodDescriptor, + boolean isStatic, + int variableIndex) + { + int parameterIndex = 0; + int parameterNumber = 0; + + // Is it a non-static method? + if (!isStatic) + { + if (variableIndex == 0) + { + return 0; + } + + variableIndex--; + parameterNumber++; + } + + // Loop over all variables until we've found the right index. + InternalTypeEnumeration internalTypeEnumeration = + new InternalTypeEnumeration(internalMethodDescriptor); + + while (internalTypeEnumeration.hasMoreTypes()) + { + if (variableIndex == parameterIndex) + { + return parameterNumber; + } + + String internalType = internalTypeEnumeration.nextType(); + + parameterIndex += internalTypeSize(internalType); + parameterNumber++; + } + + return -1; + } + + + /** + * Returns the variable index corresponding to the given parameter number + * in the given internal method descriptor. This accounts for long and + * double parameters taking up two spaces, and a non-static method taking + * up an additional entry. The method returns 0 if the number corresponds + * to the 'this' parameter and -1 if the number does not correspond to a + * parameter. + * @param internalMethodDescriptor the internal method descriptor, + * e.g. "(IDI)Z". + * @param accessFlags the access flags of the method, + * e.g. 0. + * @param parameterNumber the parameter number, + * e.g. 3. + * @return the corresponding variable index, + * e.g. 4. + */ + public static int internalMethodVariableIndex(String internalMethodDescriptor, + int accessFlags, + int parameterNumber) + { + return internalMethodVariableIndex(internalMethodDescriptor, + (accessFlags & ClassConstants.ACC_STATIC) != 0, + parameterNumber); + } + + + /** + * Returns the parameter index in the given internal method descriptor, + * corresponding to the given variable number. This accounts for long and + * double parameters taking up two spaces, and a non-static method taking + * up an additional entry. The method returns 0 if the number corresponds + * to the 'this' parameter and -1 if the number does not correspond to a + * parameter. + * @param internalMethodDescriptor the internal method descriptor, + * e.g. "(IDI)Z". + * @param isStatic specifies whether the method is static, + * e.g. false. + * @param parameterNumber the parameter number, + * e.g. 3. + * @return the corresponding variable index, + * e.g. 4. + */ + public static int internalMethodVariableIndex(String internalMethodDescriptor, + boolean isStatic, + int parameterNumber) + { + int variableNumber = 0; + int variableIndex = isStatic ? 0 : 1; + + // Loop over the given number of parameters. + InternalTypeEnumeration internalTypeEnumeration = + new InternalTypeEnumeration(internalMethodDescriptor); + + for (int counter = 0; counter < parameterNumber; counter++) + { + String internalType = internalTypeEnumeration.nextType(); + + variableIndex += internalTypeSize(internalType); + } + + return variableIndex; + } + + + /** + * Returns the internal type of the parameter in the given method descriptor, + * at the given index. + * + * @param internalMethodDescriptor the internal method descriptor + * e.g. "(IDI)Z". + * @param parameterIndex the parameter index, e.g. 1. + * @return the parameter's type, e.g. "D". + */ + public static String internalMethodParameterType(String internalMethodDescriptor, + int parameterIndex) + { + InternalTypeEnumeration typeEnum = new InternalTypeEnumeration(internalMethodDescriptor); + String type = null; + for (int i = 0; i <= parameterIndex; i++) + { + type = typeEnum.nextType(); + } + return type; + } + + /** * Returns the size taken up on the stack by the given internal type. * The size is 1, except for long and double types, for which it is 2, diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/DescriptorClassEnumeration.java proguard-6.2.0/core/src/proguard/classfile/util/DescriptorClassEnumeration.java --- proguard-6.0.3/core/src/proguard/classfile/util/DescriptorClassEnumeration.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/DescriptorClassEnumeration.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/DynamicClassReferenceInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/DynamicClassReferenceInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/DynamicClassReferenceInitializer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/DynamicClassReferenceInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java 2018-01-19 08:05:53.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/EnumFieldReferenceInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/EnumFieldReferenceInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/EnumFieldReferenceInitializer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/EnumFieldReferenceInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/ExternalTypeEnumeration.java proguard-6.2.0/core/src/proguard/classfile/util/ExternalTypeEnumeration.java --- proguard-6.0.3/core/src/proguard/classfile/util/ExternalTypeEnumeration.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/ExternalTypeEnumeration.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/InstructionSequenceMatcher.java proguard-6.2.0/core/src/proguard/classfile/util/InstructionSequenceMatcher.java --- proguard-6.0.3/core/src/proguard/classfile/util/InstructionSequenceMatcher.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/InstructionSequenceMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -454,6 +454,21 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + DynamicConstant dynamicPatternConstant = (DynamicConstant)patternConstant; + + // Check the bootstrap method and the name and type. + matchingConstant = + matchingConstantIndices(clazz, + dynamicConstant.getBootstrapMethodAttributeIndex(), + dynamicPatternConstant.getBootstrapMethodAttributeIndex()) && + matchingConstantIndices(clazz, + dynamicConstant.getNameAndTypeIndex(), + dynamicPatternConstant.getNameAndTypeIndex()); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { InvokeDynamicConstant invokeDynamicPatternConstant = (InvokeDynamicConstant)patternConstant; diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/InternalTypeEnumeration.java proguard-6.2.0/core/src/proguard/classfile/util/InternalTypeEnumeration.java --- proguard-6.0.3/core/src/proguard/classfile/util/InternalTypeEnumeration.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/InternalTypeEnumeration.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -36,11 +36,12 @@ */ public class InternalTypeEnumeration { - private String descriptor; - private int formalTypeParametersIndex; - private int openIndex; - private int closeIndex; - private int index; + private final String descriptor; + private final int formalTypeParametersIndex; + private final int openIndex; + private final int closeIndex; + + private int index; /** @@ -51,6 +52,7 @@ this.descriptor = descriptor; // Find any formal type parameters. + int formalTypeParametersIndex = 0; if (descriptor.charAt(0) == ClassConstants.TYPE_GENERIC_START) { formalTypeParametersIndex = 1; @@ -76,6 +78,8 @@ while (nestingLevel > 0); } + this.formalTypeParametersIndex = formalTypeParametersIndex;; + this.openIndex = descriptor.indexOf(ClassConstants.METHOD_ARGUMENTS_OPEN, formalTypeParametersIndex); @@ -83,6 +87,61 @@ descriptor.indexOf(ClassConstants.METHOD_ARGUMENTS_CLOSE, openIndex) : descriptor.length(); + reset(); + } + + + /** + * Returns the number of types contained in the descriptor. This + * is the number of types that the enumeration will return. + */ + public int typeCount() + { + reset(); + + int count = 0; + + while (hasMoreTypes()) + { + nextType(); + + count++; + } + + reset(); + + return count; + } + + + /** + * Returns the total size of the types contained in the descriptor. + * This accounts for long and double parameters taking up two entries. + */ + public int typesSize() + { + reset(); + + int size = 0; + + while (hasMoreTypes()) + { + String type = nextType(); + + size += ClassUtil.internalTypeSize(type); + } + + reset(); + + return size; + } + + + /** + * Resets the enumeration. + */ + private void reset() + { this.index = openIndex >= 0 ? openIndex + 1 : formalTypeParametersIndex; diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/MemberFinder.java proguard-6.2.0/core/src/proguard/classfile/util/MemberFinder.java --- proguard-6.0.3/core/src/proguard/classfile/util/MemberFinder.java 2018-01-28 00:14:39.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/MemberFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -24,8 +24,8 @@ import proguard.classfile.visitor.*; /** - * This class provides methods to find class members in a given class or in its - * hierarchy. + * This utility class provides methods to find class members in a given class + * or in its hierarchy. * * @author Eric Lafortune */ @@ -135,9 +135,6 @@ String descriptor, boolean isField) { - // Organize a search in the hierarchy of superclasses and interfaces. - // The class member may be in a different class, if the code was - // compiled with "-target 1.2" or higher (the default in JDK 1.4). try { boolean containsWildcards = @@ -147,14 +144,18 @@ this.clazz = null; this.member = null; + // The class member may be in a different class, as of Java 1.2. + // The class member may be private in a nest member, as of Java 11. // Check the accessibility from the referencing class, if any - // (non-dummy). + // (non-dummy), taking into account access flags and nests. MemberVisitor memberVisitor = referencingClass != null && referencingClass.getName() != null ? new MemberClassAccessFilter(referencingClass, this) : this; + // We'll return with a MemberFoundException as soon as we've found + // the class member. clazz.hierarchyAccept(true, searchHierarchy, searchHierarchy, diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/MethodLinker.java proguard-6.2.0/core/src/proguard/classfile/util/MethodLinker.java --- proguard-6.0.3/core/src/proguard/classfile/util/MethodLinker.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/MethodLinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/NestHostFinder.java proguard-6.2.0/core/src/proguard/classfile/util/NestHostFinder.java --- proguard-6.0.3/core/src/proguard/classfile/util/NestHostFinder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/NestHostFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.util; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.visitor.*; + +/** + * This utility class can find the nest host class names of given classes. + * + * @author Eric Lafortune + */ +public class NestHostFinder +extends SimplifiedVisitor +implements ClassVisitor, + AttributeVisitor +{ + private String nestHostClassName; + + + /** + * Returns whether the two given classes are in the same nest. + */ + public boolean inSameNest(Clazz class1, Clazz class2) + { + // Are the classes the same? + if (class1.equals(class2)) + { + return true; + } + + // Do the classes have the same nest host? + String nestHostClassName1 = findNestHostClassName(class1); + String nestHostClassName2 = findNestHostClassName(class2); + + return nestHostClassName1.equals(nestHostClassName2); + } + + + /** + * Returns the class name of the nest host of the given class. + * This may be the class itself, if the class doesn't have a nest host + * attribute (including for class versions below Java 11 and for library + * classes). + */ + public String findNestHostClassName(Clazz clazz) + { + // The default is the name of the class itself. + nestHostClassName = clazz.getName(); + + // Look for an explicit attribute. + clazz.accept(this); + + // Return the found name. + return nestHostClassName; + } + + + // Implementations for ClassVisitor. + + + public void visitProgramClass(ProgramClass programClass) + { + // The nest host attribute only exists since Java 10. + if (programClass.u4version >= ClassConstants.CLASS_VERSION_10) + { + programClass.attributesAccept(this); + } + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + // Library classes don't store their versions or attributes. + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + // Remember the class name of the nest host. + nestHostClassName = clazz.getClassName(nestHostAttribute.u2hostClassIndex); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/PrimitiveArrayConstantReplacer.java proguard-6.2.0/core/src/proguard/classfile/util/PrimitiveArrayConstantReplacer.java --- proguard-6.0.3/core/src/proguard/classfile/util/PrimitiveArrayConstantReplacer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/PrimitiveArrayConstantReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/SimplifiedVisitor.java proguard-6.2.0/core/src/proguard/classfile/util/SimplifiedVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/util/SimplifiedVisitor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/SimplifiedVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -165,6 +165,12 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + visitAnyConstant(clazz, dynamicConstant); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { visitAnyConstant(clazz, invokeDynamicConstant); @@ -400,6 +406,18 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + visitAnyAttribute(clazz, nestHostAttribute); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + visitAnyAttribute(clazz, nestMembersAttribute); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { visitAnyAttribute(clazz, moduleAttribute); diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/StringReferenceInitializer.java proguard-6.2.0/core/src/proguard/classfile/util/StringReferenceInitializer.java --- proguard-6.0.3/core/src/proguard/classfile/util/StringReferenceInitializer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/StringReferenceInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/StringSharer.java proguard-6.2.0/core/src/proguard/classfile/util/StringSharer.java --- proguard-6.0.3/core/src/proguard/classfile/util/StringSharer.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/StringSharer.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -69,7 +69,7 @@ if (libraryClass.interfaceNames != null) { String[] interfaceNames = libraryClass.interfaceNames; - Clazz[] interfaceClasses = new Clazz[interfaceNames.length]; + Clazz[] interfaceClasses = libraryClass.interfaceClasses; for (int index = 0; index < interfaceNames.length; index++) { diff -Nru proguard-6.0.3/core/src/proguard/classfile/util/WarningPrinter.java proguard-6.2.0/core/src/proguard/classfile/util/WarningPrinter.java --- proguard-6.0.3/core/src/proguard/classfile/util/WarningPrinter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/util/WarningPrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,7 +22,7 @@ import proguard.util.*; -import java.io.PrintStream; +import java.io.PrintWriter; import java.util.List; /** @@ -32,26 +32,17 @@ */ public class WarningPrinter { - private final PrintStream printStream; + private final PrintWriter printWriter; private final StringMatcher classFilter; private int warningCount; /** - * Creates a new WarningPrinter that prints to the System.err print stream. + * Creates a new WarningPrinter that prints to the given print writer. */ - public WarningPrinter() + public WarningPrinter(PrintWriter printWriter) { - this(System.err); - } - - - /** - * Creates a new WarningPrinter that prints to the given print stream. - */ - public WarningPrinter(PrintStream printStream) - { - this.printStream = printStream; + this.printWriter = printWriter; this.classFilter = null; } @@ -60,9 +51,9 @@ * Creates a new WarningPrinter that prints to the given print stream, * except if the names of any involved classes matches the given filter. */ - public WarningPrinter(PrintStream printStream, List classFilter) + public WarningPrinter(PrintWriter printWriter, List classFilter) { - this.printStream = printStream; + this.printWriter = printWriter; this.classFilter = classFilter == null ? null : new ListParser(new ClassNameParser()).parse(classFilter); } @@ -120,7 +111,7 @@ */ private void print(String warning) { - printStream.println(warning); + printWriter.println(warning); warningCount++; } diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/AllClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/AllClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/AllClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/AllClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/AllFieldVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/AllFieldVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/AllFieldVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/AllFieldVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/AllMemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/AllMemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/AllMemberVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/AllMemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/AllMethodVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/AllMethodVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/AllMethodVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/AllMethodVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/BottomClassFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/BottomClassFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/BottomClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/BottomClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassAccessFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassAccessFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassAccessFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassAccessFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -24,7 +24,7 @@ /** - * This ClassVisitor delegates its visits to another given + * This ClassVisitor delegates its visits to another given * ClassVisitor, but only when the visited class * has the proper access flags. * diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassCleaner.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassCleaner.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassCleaner.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassCleaner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassCollector.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassCollector.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassCollector.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassCounter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassCounter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassCounter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassCounter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassHierarchyTraveler.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassHierarchyTraveler.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassHierarchyTraveler.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassHierarchyTraveler.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassNameFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassNameFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassNameFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassNameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolFiller.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolFiller.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolFiller.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolFiller.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolRemover.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolRemover.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolRemover.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolRemover.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPoolVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPoolVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPresenceFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPresenceFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPresenceFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPresenceFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPrinter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPrinter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassPrinter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassPrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -245,6 +245,16 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + println(visitorInfo(dynamicConstant) + " Dynamic [bootstrap method index = " + dynamicConstant.u2bootstrapMethodAttributeIndex + "]:"); + + indent(); + clazz.constantPoolEntryAccept(dynamicConstant.u2nameAndTypeIndex, this); + outdent(); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { println(visitorInfo(invokeDynamicConstant) + " InvokeDynamic [bootstrap method index = " + invokeDynamicConstant.u2bootstrapMethodAttributeIndex + "]:"); @@ -484,6 +494,28 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + println(visitorInfo(nestHostAttribute) + + " Nest host attribute:"); + + indent(); + clazz.constantPoolEntryAccept(nestHostAttribute.u2hostClassIndex, this); + outdent(); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + println(visitorInfo(nestMembersAttribute) + + " Nest members attribute:"); + + indent(); + nestMembersAttribute.memberClassConstantsAccept(clazz, this); + outdent(); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { println(visitorInfo(moduleAttribute) + @@ -1165,7 +1197,7 @@ public void visitSuperTypeTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, SuperTypeTargetInfo superTypeTargetInfo) { println("Target (type = 0x" + Integer.toHexString(superTypeTargetInfo.u1targetType) + "): " + - (superTypeTargetInfo.u2superTypeIndex == 0xffff ? + (superTypeTargetInfo.u2superTypeIndex == SuperTypeTargetInfo.EXTENDS_INDEX ? "super class" : "interface #" + superTypeTargetInfo.u2superTypeIndex)); } diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassVersionFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassVersionFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassVersionFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassVersionFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassVersionSetter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassVersionSetter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassVersionSetter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassVersionSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java proguard-6.2.0/core/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ConstructorMethodFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ConstructorMethodFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ConstructorMethodFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ConstructorMethodFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/DotClassClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/DotClassClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/DotClassClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/DotClassClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/DynamicReturnedClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/DynamicReturnedClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/DynamicReturnedClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/DynamicReturnedClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -27,7 +27,8 @@ /** * This ConstantVisitor lets a given ClassVisitor visit all the referenced - * classes that are returned by the invoke dynamic constants that it visits. + * classes that are returned by the dynamic constants and invoke dynamic + * constants that it visits. * * @author Eric Lafortune */ @@ -49,6 +50,24 @@ public void visitAnyConstant(Clazz clazz, Constant constant) {} + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + // Is the method returning a class type? + Clazz[] referencedClasses = dynamicConstant.referencedClasses; + if (referencedClasses != null && + referencedClasses.length > 0 && + ClassUtil.isInternalClassType(ClassUtil.internalMethodReturnType(dynamicConstant.getType(clazz)))) + { + // Let the visitor visit the return type class, if any. + Clazz referencedClass = referencedClasses[referencedClasses.length - 1]; + if (referencedClass != null) + { + referencedClass.accept(classVisitor); + } + } + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { // Is the method returning a class type? diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptClassesFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptClassesFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptClassesFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptClassesFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptClassFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptClassFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionCounter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionCounter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionCounter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionCounter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionHandlerFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionHandlerFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionHandlerFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionHandlerFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionOffsetFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionOffsetFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionOffsetFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionOffsetFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionRangeFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionRangeFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ExceptionRangeFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ExceptionRangeFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/FunctionalInterfaceFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/FunctionalInterfaceFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/FunctionalInterfaceFilter.java 2018-03-04 13:57:23.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/FunctionalInterfaceFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,6 +22,8 @@ import proguard.classfile.*; +import java.util.*; + /** * This ClassVisitor delegates its visits to another given * ClassVisitor, but only for functional interfaces, that @@ -75,22 +77,34 @@ return false; } - // Count the abstract methods in the interface hierarchy. - // Subtract any corresponding default methods, since only abstract - // methods that don't have a default implementation count. - // TODO: Find a better way to count default methods, since there may be more of them for a single abstract method, or we can find one via different paths. - MemberCounter abstractMethodCounter = new MemberCounter(); - MemberCounter defaultMethodCounter = new MemberCounter(); + // Count the abstract methods and the default methods in the + // interface hierarchy. + Set abstractMethods = new HashSet(); + Set defaultMethods = new HashSet(); + clazz.hierarchyAccept(true, false, true, false, new AllMethodVisitor( - new MemberAccessFilter(ClassConstants.ACC_ABSTRACT, 0, new MultiMemberVisitor( - abstractMethodCounter, - new SimilarMemberVisitor(clazz, true, false, true, false, + new MemberAccessFilter(ClassConstants.ACC_ABSTRACT, 0, + new MemberCollector(false, true, true, abstractMethods)), + new MemberAccessFilter(0, ClassConstants.ACC_ABSTRACT, - defaultMethodCounter)) - )))); + new MemberCollector(false, true, true, defaultMethods)) + ))); + + // Ignore marker interfaces. + if (abstractMethods.size() == 0) + { + return false; + } - return abstractMethodCounter.getCount() - defaultMethodCounter.getCount() == 1; + // Subtract default methods, since only abstract methods that don't + // have default implementations count. + abstractMethods.removeAll(defaultMethods); + + // Also consider this a functional interface if all abstract methods + // have default implementations. Dynamic invocations may explicitly + // specify the intended single abstract method. [PGD-756] + return abstractMethods.size() <= 1; } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ImplementedClassFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ImplementedClassFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ImplementedClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ImplementedClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -23,30 +23,48 @@ import proguard.classfile.*; /** - * This ClassVisitor delegates its visits to another given - * ClassVisitor, except for classes that extend or implement - * a given class. + * This ClassVisitor delegates its visits to one of two given + * ClassVisitors, depending on whether the visited classes + * extend/implement a given class or not. + * + * Filter: + * - accepted: the visited class extends/implements the given class. + * - rejected: the visited class does not extend/implement the given class. * * @author Eric Lafortune */ public class ImplementedClassFilter implements ClassVisitor { private final Clazz implementedClass; - private final ClassVisitor classVisitor; + private final boolean includeImplementedClass; + private final ClassVisitor acceptedClassVisitor; + private final ClassVisitor rejectedClassVisitor; /** * Creates a new ImplementedClassFilter. - * @param implementedClass the class whose implementations will not be - * visited. - * @param classVisitor the ClassVisitor to which visits will - * be delegated. + * + * @param implementedClass the class whose implementations will + * be accepted. + * @param includeImplementedClass if true, the implemented class itself + * will also be accepted, otherwise it + * will be rejected. + * @param acceptedClassVisitor the ClassVisitor to which + * visits of classes implementing the given + * class will be delegated. + * @param rejectedClassVisistor the ClassVisitor to which + * visits of classes not implementing the + * given class will be delegated. */ public ImplementedClassFilter(Clazz implementedClass, - ClassVisitor classVisitor) + boolean includeImplementedClass, + ClassVisitor acceptedClassVisitor, + ClassVisitor rejectedClassVisistor) { this.implementedClass = implementedClass; - this.classVisitor = classVisitor; + this.includeImplementedClass = includeImplementedClass; + this.acceptedClassVisitor = acceptedClassVisitor; + this.rejectedClassVisitor = rejectedClassVisistor; } @@ -54,18 +72,29 @@ public void visitProgramClass(ProgramClass programClass) { - if (!programClass.extendsOrImplements(implementedClass)) + ClassVisitor visitor = delegateVisitor(programClass); + if (visitor != null) { - classVisitor.visitProgramClass(programClass); + visitor.visitProgramClass(programClass); } } - public void visitLibraryClass(LibraryClass libraryClass) { - if (!libraryClass.extendsOrImplements(implementedClass)) + ClassVisitor visitor = delegateVisitor(libraryClass); + if (visitor != null) { - classVisitor.visitLibraryClass(libraryClass); + visitor.visitLibraryClass(libraryClass); } } -} \ No newline at end of file + + + // Small utility methods. + + private ClassVisitor delegateVisitor(Clazz clazz) + { + return clazz.extendsOrImplements(implementedClass) && + (clazz != implementedClass || includeImplementedClass) ? + acceptedClassVisitor : rejectedClassVisitor; + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/InitializerMethodFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/InitializerMethodFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/InitializerMethodFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/InitializerMethodFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/LibraryClassFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/LibraryClassFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/LibraryClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/LibraryClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/LibraryMemberFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/LibraryMemberFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/LibraryMemberFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/LibraryMemberFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessFlagCleaner.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessFlagCleaner.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessFlagCleaner.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessFlagCleaner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessFlagSetter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessFlagSetter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessFlagSetter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessFlagSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessSetter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessSetter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberAccessSetter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberAccessSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.util.AccessUtil; + +/** + * This MemberVisitor sets the access part of the access flags of + * the program class members that its visits to a given value. + * + * @see ClassConstants + * + * @author Eric Lafortune + */ +public class MemberAccessSetter + implements MemberVisitor +{ + private final int accessFlags; + + + /** + * Creates a new MemberAccessSetter. + * @param accessFlags the member access flags to be set. + */ + public MemberAccessSetter(int accessFlags) + { + this.accessFlags = accessFlags; + } + + + // Implementations for MemberVisitor. + + public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) {} + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) {} + + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + programField.u2accessFlags = + AccessUtil.replaceAccessFlags(programField.u2accessFlags, accessFlags); + } + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + programMethod.u2accessFlags = + AccessUtil.replaceAccessFlags(programMethod.u2accessFlags, accessFlags); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberClassAccessFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberClassAccessFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberClassAccessFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberClassAccessFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -21,6 +21,8 @@ package proguard.classfile.visitor; import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; import proguard.classfile.util.*; /** @@ -33,8 +35,11 @@ public class MemberClassAccessFilter implements MemberVisitor { - private final Clazz referencingClass; - private final MemberVisitor memberVisitor; + private final NestHostFinder nestHostFinder = new NestHostFinder(); + private final Clazz referencingClass; + private final String referencingNestHostClassName; + private final MemberVisitor memberVisitor; + /** @@ -46,8 +51,9 @@ public MemberClassAccessFilter(Clazz referencingClass, MemberVisitor memberVisitor) { - this.referencingClass = referencingClass; - this.memberVisitor = memberVisitor; + this.referencingClass = referencingClass; + this.referencingNestHostClassName = nestHostFinder.findNestHostClassName(referencingClass); + this.memberVisitor = memberVisitor; } @@ -96,11 +102,11 @@ int accessLevel = AccessUtil.accessLevel(memberAccessFlags); return - (accessLevel >= AccessUtil.PUBLIC ) || - (accessLevel >= AccessUtil.PRIVATE && referencingClass.equals(clazz) ) || + (accessLevel >= AccessUtil.PUBLIC ) || + (accessLevel >= AccessUtil.PRIVATE && nestHostFinder.inSameNest(referencingClass, clazz)) || (accessLevel >= AccessUtil.PACKAGE_VISIBLE && (ClassUtil.internalPackageName(referencingClass.getName()).equals( - ClassUtil.internalPackageName(clazz.getName())))) || - (accessLevel >= AccessUtil.PROTECTED && (referencingClass.extends_(clazz) || - referencingClass.extendsOrImplements(clazz)) ); + ClassUtil.internalPackageName(clazz.getName()))) ) || + (accessLevel >= AccessUtil.PROTECTED && (referencingClass.extends_(clazz) || + referencingClass.extendsOrImplements(clazz)) ); } } diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberCollector.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberCollector.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberCollector.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberCounter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberCounter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberCounter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberCounter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberDescriptorFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberDescriptorFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberDescriptorFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberDescriptorFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberDescriptorReferencedClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberDescriptorReferencedClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberDescriptorReferencedClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberDescriptorReferencedClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberNameFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberNameFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberNameFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberNameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberToClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberToClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberToClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberToClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MemberVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MethodCollector.java proguard-6.2.0/core/src/proguard/classfile/visitor/MethodCollector.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MethodCollector.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MethodCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MethodImplementationFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/MethodImplementationFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MethodImplementationFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MethodImplementationFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MethodImplementationTraveler.java proguard-6.2.0/core/src/proguard/classfile/visitor/MethodImplementationTraveler.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MethodImplementationTraveler.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MethodImplementationTraveler.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MultiClassPoolVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MultiClassPoolVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MultiClassPoolVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MultiClassPoolVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MultiClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MultiClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MultiClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MultiClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MultiConstantVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MultiConstantVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MultiConstantVisitor.java 2018-04-12 10:52:31.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MultiConstantVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/MultiMemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/MultiMemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/MultiMemberVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/MultiMemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/NamedClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/NamedClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/NamedClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/NamedClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/NamedFieldVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/NamedFieldVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/NamedFieldVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/NamedFieldVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/NamedMethodVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/NamedMethodVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/NamedMethodVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/NamedMethodVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ParallelAllClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ParallelAllClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ParallelAllClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ParallelAllClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ParameterVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ParameterVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ParameterVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ParameterVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ProgramClassFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ProgramClassFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ProgramClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ProgramClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ProgramMemberFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/ProgramMemberFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ProgramMemberFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ProgramMemberFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ReferencedClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ReferencedClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ReferencedClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ReferencedClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java 2018-03-29 10:12:22.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/SignatureAttributeReferencedClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/SignatureAttributeReferencedClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/SignatureAttributeReferencedClassVisitor.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/SignatureAttributeReferencedClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This AttributeVisitor lets a given ClassVisitor visit all the + * classes referenced by the type descriptors of the signatures that it visits. + * + * @author Joachim Vandersmissen + */ +public class SignatureAttributeReferencedClassVisitor +extends SimplifiedVisitor +implements AttributeVisitor +{ + private final ClassVisitor classVisitor; + + + public SignatureAttributeReferencedClassVisitor(ClassVisitor classVisitor) + { + this.classVisitor = classVisitor; + } + + + // Implementations for AttributeVisitor + + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) + { + + } + + + public void visitSignatureAttribute(Clazz clazz, + SignatureAttribute signatureAttribute) + { + signatureAttribute.referencedClassesAccept(classVisitor); + } + + + public void visitSignatureAttribute(Clazz clazz, + Field field, + SignatureAttribute signatureAttribute) + { + signatureAttribute.referencedClassesAccept(classVisitor); + } + + + public void visitSignatureAttribute(Clazz clazz, + Method method, + SignatureAttribute signatureAttribute) + { + signatureAttribute.referencedClassesAccept(classVisitor); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/SimilarMemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/SimilarMemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/SimilarMemberVisitor.java 2018-03-29 10:12:22.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/SimilarMemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/SimpleClassPrinter.java proguard-6.2.0/core/src/proguard/classfile/visitor/SimpleClassPrinter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/SimpleClassPrinter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/SimpleClassPrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/SingleTimeClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/SingleTimeClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/SingleTimeClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/SingleTimeClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/SubclassFilter.java proguard-6.2.0/core/src/proguard/classfile/visitor/SubclassFilter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/SubclassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/SubclassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/SubclassTraveler.java proguard-6.2.0/core/src/proguard/classfile/visitor/SubclassTraveler.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/SubclassTraveler.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/SubclassTraveler.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/VariableClassVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/VariableClassVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/VariableClassVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/VariableClassVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/VariableMemberVisitor.java proguard-6.2.0/core/src/proguard/classfile/visitor/VariableMemberVisitor.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/VariableMemberVisitor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/VariableMemberVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/classfile/visitor/VisitorInfoSetter.java proguard-6.2.0/core/src/proguard/classfile/visitor/VisitorInfoSetter.java --- proguard-6.0.3/core/src/proguard/classfile/visitor/VisitorInfoSetter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/visitor/VisitorInfoSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,171 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.preverification.*; +import proguard.classfile.attribute.preverification.visitor.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.Constant; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This visitor sets a fixed info object on all the visitor accepters + * that it visits. + * + * @author Eric Lafortune + */ +public class VisitorInfoSetter +extends SimplifiedVisitor +implements ClassVisitor, + ConstantVisitor, + MemberVisitor, + AttributeVisitor, + ExceptionInfoVisitor, + InnerClassesInfoVisitor, + StackMapFrameVisitor, + VerificationTypeVisitor, + LocalVariableInfoVisitor, + LocalVariableTypeInfoVisitor, + AnnotationVisitor, + TypeAnnotationVisitor, + ElementValueVisitor +{ + private final Object visitorInfo; + + + /** + * Creates a new VisitorInfoSetter that sets the given info on all visitor + * accepters that it visits. + */ + public VisitorInfoSetter(Object visitorInfo) + { + this.visitorInfo = visitorInfo; + } + + + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) + { + clazz.setVisitorInfo(visitorInfo); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) + { + constant.setVisitorInfo(visitorInfo); + } + + + // Implementations for MemberVisitor. + + public void visitAnyMember(Clazz clazz, Member member) + { + member.setVisitorInfo(visitorInfo); + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) + { + attribute.setVisitorInfo(visitorInfo); + } + + + // Implementations for InnerClassesInfoVisitor. + + public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) + { + innerClassesInfo.setVisitorInfo(visitorInfo); + } + + + // Implementations for ExceptionInfoVisitor. + + public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) + { + exceptionInfo.setVisitorInfo(visitorInfo); + } + + + // Implementations for StackMapFrameVisitor. + + public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) + { + stackMapFrame.setVisitorInfo(visitorInfo); + } + + + // Implementations for VerificationTypeVisitor. + + public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) + { + verificationType.setVisitorInfo(visitorInfo); + } + + + // Implementations for LocalVariableInfoVisitor. + + public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) + { + localVariableInfo.setVisitorInfo(visitorInfo); + } + + + // Implementations for LocalVariableTypeInfoVisitor. + + public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) + { + localVariableTypeInfo.setVisitorInfo(visitorInfo); + } + + + // Implementations for AnnotationVisitor. + + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + annotation.setVisitorInfo(visitorInfo); + } + + + // Implementations for TypeAnnotationVisitor. + + public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation) + { + typeAnnotation.setVisitorInfo(visitorInfo); + } + + + // Implementations for ElementValueVisitor. + + public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) + { + elementValue.setVisitorInfo(visitorInfo); + } +} diff -Nru proguard-6.0.3/core/src/proguard/classfile/VisitorAccepter.java proguard-6.2.0/core/src/proguard/classfile/VisitorAccepter.java --- proguard-6.0.3/core/src/proguard/classfile/VisitorAccepter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/classfile/VisitorAccepter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ClassMemberChecker.java proguard-6.2.0/core/src/proguard/ClassMemberChecker.java --- proguard-6.0.3/core/src/proguard/ClassMemberChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ClassMemberChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ClassPathEntry.java proguard-6.2.0/core/src/proguard/ClassPathEntry.java --- proguard-6.0.3/core/src/proguard/ClassPathEntry.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ClassPathEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ClassPath.java proguard-6.2.0/core/src/proguard/ClassPath.java --- proguard-6.0.3/core/src/proguard/ClassPath.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ClassPath.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ClassSpecification.java proguard-6.2.0/core/src/proguard/ClassSpecification.java --- proguard-6.0.3/core/src/proguard/ClassSpecification.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ClassSpecification.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ClassSpecificationVisitorFactory.java proguard-6.2.0/core/src/proguard/ClassSpecificationVisitorFactory.java --- proguard-6.0.3/core/src/proguard/ClassSpecificationVisitorFactory.java 2018-03-25 23:17:28.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ClassSpecificationVisitorFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -392,16 +392,41 @@ (MemberSpecification)memberSpecifications.get(index); multiClassVisitor.addClassVisitor( - createClassVisitor(memberSpecification, - isField, - memberVisitor, - attributeVisitor, - variableStringMatchers)); + createNonTestingClassVisitor(memberSpecification, + isField, + memberVisitor, + attributeVisitor, + variableStringMatchers)); } } } + /** + * Creates a new ClassVisitor to efficiently travel to the specified class + * members and attributes. + * + * @param memberSpecification the specification of the class member(s) to + * visit. + * @param memberVisitor the MemberVisitor to be applied to matching + * class member(s). + * @param variableStringMatchers a mutable list of VariableStringMatcher + * instances that match the wildcards. + */ + protected ClassVisitor createNonTestingClassVisitor(MemberSpecification memberSpecification, + boolean isField, + MemberVisitor memberVisitor, + AttributeVisitor attributeVisitor, + List variableStringMatchers) + { + return createClassVisitor(memberSpecification, + isField, + memberVisitor, + attributeVisitor, + variableStringMatchers); + } + + /** * Constructs a ClassPoolVisitor that conditionally applies the given * ClassPoolVisitor for all classes that match the given class diff -Nru proguard-6.0.3/core/src/proguard/configuration/ConfigurationLogger.java proguard-6.2.0/core/src/proguard/configuration/ConfigurationLogger.java --- proguard-6.0.3/core/src/proguard/configuration/ConfigurationLogger.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/configuration/ConfigurationLogger.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingAdder.java proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingAdder.java --- proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingAdder.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -67,7 +67,7 @@ /** - * Instrumets the given program class pool. + * Instruments the given program class pool. */ public void execute(ClassPool programClassPool, ClassPool libraryClassPool, diff -Nru proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceConstants.java proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceConstants.java --- proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceConstants.java 2018-01-28 00:14:39.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -30,7 +30,9 @@ import static proguard.optimize.peephole.InstructionSequenceReplacer.catch_; /** - * This class contains a set of instruction sequences for accessing class information via reflection, and replacement instructions that add logging information on the reflection that is used. + * This class contains a set of instruction sequences for accessing class + * information via reflection, and replacement instructions that add logging + * information on the reflection that is used. * * @author Johan Leys */ @@ -38,7 +40,7 @@ { private static String LOGGER_CLASS_NAME = ClassUtil.internalClassName(ConfigurationLogger.class.getName()); - // Exceptions classes. + // Exception classes. public static final String NAME_CLASS_NOT_FOUND_EXCEPTION = "java/lang/ClassNotFoundException"; public static final String NAME_NO_SUCH_FIELD_EXCEPTION = "java/lang/NoSuchFieldException"; public static final String NAME_NO_SUCH_METHOD_EXCEPTION = "java/lang/NoSuchMethodException"; @@ -68,7 +70,6 @@ private final InstructionSequenceReplacer.Label NO_SUCH_FIELD_EXCEPTION; private final InstructionSequenceReplacer.Label IO_EXCEPTION; private final InstructionSequenceReplacer.Label RUNTIME_EXCEPTION; - private final InstructionSequenceReplacer.Label UNSATISFIED_LINK_ERROR; /** * Creates a new instance of ResourceIdInstructionSequenceConstants, @@ -102,10 +103,6 @@ catch_(TRY_START.offset(), TRY_END.offset(), constantPoolEditor.addClassConstant(NAME_RUNTIME_EXCEPTION, null)); - UNSATISFIED_LINK_ERROR = - catch_(TRY_START.offset(), - TRY_END.offset(), - constantPoolEditor.addClassConstant(NAME_UNSATISFIED_LINK_ERROR, null)); RESOURCE = new Instruction[][][] { @@ -344,134 +341,6 @@ .invokestatic(LOGGER_CLASS_NAME, "logGetFields", "(Ljava/lang/String;Ljava/lang/Class;)V") .invokevirtual("java/lang/Class", "getFields", "()[Ljava/lang/reflect/Field;").__() }, - - // Resource files. - - // System.loadLibrary(String) - { - ____.ldc_(CONSTANT_INDEX) - .invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY).__(), - - ____.ldc_(CONSTANT_INDEX) - .label(TRY_START) - .invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY) - .label(TRY_END) - .goto_(CATCH_END.offset()) - .catch_(UNSATISFIED_LINK_ERROR) - .ldc_(CLASS_NAME) - .ldc_(CONSTANT_INDEX) - .invokestatic(LOGGER_CLASS_NAME, "logLoadLibrary", "(Ljava/lang/String;Ljava/lang/String;)V") - .athrow() - .label(CATCH_END).__() - }, - { - ____.invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY).__(), - - ____.dup() - .astore(LOCAL_VARIABLE_INDEX_1) - .label(TRY_START) - .invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY) - .label(TRY_END) - .goto_(CATCH_END.offset()) - .catch_(UNSATISFIED_LINK_ERROR) - .ldc_(CLASS_NAME) - .aload(LOCAL_VARIABLE_INDEX_1) - .invokestatic(LOGGER_CLASS_NAME, "logLoadLibrary", "(Ljava/lang/String;Ljava/lang/String;)V") - .athrow() - .label(CATCH_END).__() - }, - - // System.load(String) - { - ____.ldc_(CONSTANT_INDEX) - .invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD, - ClassConstants.METHOD_TYPE_LOAD).__(), - - ____.ldc_(CONSTANT_INDEX) - .label(TRY_START) - .invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD, - ClassConstants.METHOD_TYPE_LOAD) - .label(TRY_END) - .goto_(CATCH_END.offset()) - .catch_(UNSATISFIED_LINK_ERROR) - .ldc_(CLASS_NAME) - .ldc_(CONSTANT_INDEX) - .invokestatic(LOGGER_CLASS_NAME, "logLoad", "(Ljava/lang/String;Ljava/lang/String;)V") - .athrow() - .label(CATCH_END).__() - }, - { - ____.invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD, - ClassConstants.METHOD_TYPE_LOAD).__(), - - ____.dup() - .astore(LOCAL_VARIABLE_INDEX_1) - .label(TRY_START) - .invokestatic(ClassConstants.NAME_JAVA_LANG_SYSTEM, - ClassConstants.METHOD_NAME_LOAD, - ClassConstants.METHOD_TYPE_LOAD) - .label(TRY_END) - .goto_(CATCH_END.offset()) - .catch_(UNSATISFIED_LINK_ERROR) - .ldc_(CLASS_NAME) - .aload(LOCAL_VARIABLE_INDEX_1) - .invokestatic(LOGGER_CLASS_NAME, "logLoad", "(Ljava/lang/String;Ljava/lang/String;)V") - .athrow() - .label(CATCH_END).__() - }, - - // Runtime.loadLibrary(String) - { - ____.ldc_(CONSTANT_INDEX) - .invokestatic(ClassConstants.NAME_JAVA_LANG_RUNTIME, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY).__(), - - ____.ldc_(CONSTANT_INDEX) - .label(TRY_START) - .invokestatic(ClassConstants.NAME_JAVA_LANG_RUNTIME, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY) - .label(TRY_END) - .goto_(CATCH_END.offset()) - .catch_(UNSATISFIED_LINK_ERROR) - .ldc_(CLASS_NAME) - .ldc_(CONSTANT_INDEX) - .invokestatic(LOGGER_CLASS_NAME, "logLoadLibrary", "(Ljava/lang/String;Ljava/lang/String;)V") - .athrow() - .label(CATCH_END).__() - }, - { - ____.invokestatic(ClassConstants.NAME_JAVA_LANG_RUNTIME, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY).__(), - - ____.dup() - .astore(LOCAL_VARIABLE_INDEX_1) - .label(TRY_START) - .invokestatic(ClassConstants.NAME_JAVA_LANG_RUNTIME, - ClassConstants.METHOD_NAME_LOAD_LIBRARY, - ClassConstants.METHOD_TYPE_LOAD_LIBRARY) - .label(TRY_END) - .goto_(CATCH_END.offset()) - .catch_(UNSATISFIED_LINK_ERROR) - .ldc_(CLASS_NAME) - .aload(LOCAL_VARIABLE_INDEX_1) - .invokestatic(LOGGER_CLASS_NAME, "logLoadLibrary", "(Ljava/lang/String;Ljava/lang/String;)V") - .athrow() - .label(CATCH_END).__() - }, }; CONSTANTS = ____.constants(); diff -Nru proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceReplacer.java proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceReplacer.java --- proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceReplacer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingInstructionSequenceReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingInstructionSequencesReplacer.java proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingInstructionSequencesReplacer.java --- proguard-6.0.3/core/src/proguard/configuration/ConfigurationLoggingInstructionSequencesReplacer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/configuration/ConfigurationLoggingInstructionSequencesReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ConfigurationChecker.java proguard-6.2.0/core/src/proguard/ConfigurationChecker.java --- proguard-6.0.3/core/src/proguard/ConfigurationChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ConfigurationChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,7 +22,7 @@ import proguard.classfile.util.WarningPrinter; -import java.io.IOException; +import java.io.*; /** * This class performs sanity checks on a given configurations. @@ -48,6 +48,10 @@ */ public void check() throws IOException { + // We're using the system's default character encoding for writing to + // the standard output. + PrintWriter out = new PrintWriter(System.out, true); + ClassPath programJars = configuration.programJars; ClassPath libraryJars = configuration.libraryJars; @@ -111,10 +115,10 @@ !entry.isJmod() && !entry.isZip()) { - System.out.println("Note: you're writing the processed class files to a directory [" + entry.getName() + "]."); - System.out.println(" This will likely cause problems with obfuscated mixed-case class names."); - System.out.println(" You should consider writing the output to a jar file, or otherwise"); - System.out.println(" specify '-dontusemixedcaseclassnames'."); + out.println("Note: you're writing the processed class files to a directory [" + entry.getName() +"]."); + out.println(" This will likely cause problems with obfuscated mixed-case class names."); + out.println(" You should consider writing the output to a jar file, or otherwise"); + out.println(" specify '-dontusemixedcaseclassnames'."); break; } @@ -127,17 +131,17 @@ (configuration.adaptResourceFileContents.isEmpty() || configuration.adaptResourceFileContents.get(0).equals(ConfigurationConstants.ANY_FILE_KEYWORD))) { - System.out.println("Note: you're specifying '-adaptresourcefilecontents' for all resource files."); - System.out.println(" This will most likely cause problems with binary files."); + out.println("Note: you're specifying '-adaptresourcefilecontents' for all resource files."); + out.println(" This will most likely cause problems with binary files."); } // Check if all -keepclassmembers options indeed have class members. - WarningPrinter keepClassMemberNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter keepClassMemberNotePrinter = new WarningPrinter(out, configuration.note); new KeepClassMemberChecker(keepClassMemberNotePrinter).checkClassSpecifications(configuration.keep); // Check if -assumenosideffects options don't specify all methods. - WarningPrinter assumeNoSideEffectsNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter assumeNoSideEffectsNotePrinter = new WarningPrinter(out, configuration.note); new AssumeNoSideEffectsChecker(assumeNoSideEffectsNotePrinter).checkClassSpecifications(configuration.assumeNoSideEffects); @@ -145,21 +149,21 @@ int keepClassMemberNoteCount = keepClassMemberNotePrinter.getWarningCount(); if (keepClassMemberNoteCount > 0) { - System.out.println("Note: there were " + keepClassMemberNoteCount + - " '-keepclassmembers' options that didn't specify class"); - System.out.println(" members. You should specify at least some class members or consider"); - System.out.println(" if you just need '-keep'."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#classmembers)"); + out.println("Note: there were " + keepClassMemberNoteCount + + " '-keepclassmembers' options that didn't specify class"); + out.println(" members. You should specify at least some class members or consider"); + out.println(" if you just need '-keep'."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#classmembers)"); } int assumeNoSideEffectsNoteCount = assumeNoSideEffectsNotePrinter.getWarningCount(); if (assumeNoSideEffectsNoteCount > 0) { - System.out.println("Note: there were " + assumeNoSideEffectsNoteCount + + out.println("Note: there were " + assumeNoSideEffectsNoteCount + " '-assumenosideeffects' options that try to match all"); - System.out.println(" methods with wildcards. This will likely cause problems with methods like"); - System.out.println(" 'wait()' and 'notify()'. You should specify the methods more precisely."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#nosideeffects)"); + out.println(" methods with wildcards. This will likely cause problems with methods like"); + out.println(" 'wait()' and 'notify()'. You should specify the methods more precisely."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#nosideeffects)"); } } } @@ -222,4 +226,4 @@ } } } -} +} \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/ConfigurationConstants.java proguard-6.2.0/core/src/proguard/ConfigurationConstants.java --- proguard-6.0.3/core/src/proguard/ConfigurationConstants.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ConfigurationConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -62,6 +62,7 @@ public static final String ASSUME_NO_EXTERNAL_SIDE_EFFECTS_OPTION = "-assumenoexternalsideeffects"; public static final String ASSUME_NO_ESCAPING_PARAMETERS_OPTION = "-assumenoescapingparameters"; public static final String ASSUME_NO_EXTERNAL_RETURN_VALUES_OPTION = "-assumenoexternalreturnvalues"; + public static final String ASSUME_VALUES_OPTION = "-assumevalues"; public static final String ALLOW_ACCESS_MODIFICATION_OPTION = "-allowaccessmodification"; public static final String MERGE_INTERFACES_AGGRESSIVELY_OPTION = "-mergeinterfacesaggressively"; @@ -129,6 +130,11 @@ public static final String ARGUMENT_SEPARATOR_KEYWORD = ","; public static final String ANY_ARGUMENTS_KEYWORD = "..."; public static final String CLOSE_ARGUMENTS_KEYWORD = ")"; + public static final String EQUAL_KEYWORD = "="; + public static final String RETURN_KEYWORD = "return"; + public static final String FALSE_KEYWORD = "false"; + public static final String TRUE_KEYWORD = "true"; + public static final String RANGE_KEYWORD = ".."; public static final String SEPARATOR_KEYWORD = ";"; public static final String CLOSE_KEYWORD = "}"; } diff -Nru proguard-6.0.3/core/src/proguard/Configuration.java proguard-6.2.0/core/src/proguard/Configuration.java --- proguard-6.0.3/core/src/proguard/Configuration.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/Configuration.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -172,6 +172,12 @@ public List assumeNoExternalReturnValues; /** + * A list of {@link ClassSpecification} instances, with fields and methods + * that have specified fixed primitive values. + */ + public List assumeValues; + + /** * Specifies whether the access of class members can be modified. */ public boolean allowAccessModification = false; diff -Nru proguard-6.0.3/core/src/proguard/ConfigurationParser.java proguard-6.2.0/core/src/proguard/ConfigurationParser.java --- proguard-6.0.3/core/src/proguard/ConfigurationParser.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ConfigurationParser.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -175,15 +175,16 @@ else if (ConfigurationConstants.DONT_SHRINK_OPTION .startsWith(nextWord)) configuration.shrink = parseNoArgument(false); else if (ConfigurationConstants.PRINT_USAGE_OPTION .startsWith(nextWord)) configuration.printUsage = parseOptionalFile(); - else if (ConfigurationConstants.WHY_ARE_YOU_KEEPING_OPTION .startsWith(nextWord)) configuration.whyAreYouKeeping = parseClassSpecificationArguments(true, configuration.whyAreYouKeeping); + else if (ConfigurationConstants.WHY_ARE_YOU_KEEPING_OPTION .startsWith(nextWord)) configuration.whyAreYouKeeping = parseKeepClassSpecificationArguments(configuration.whyAreYouKeeping, false, false, false, null); else if (ConfigurationConstants.DONT_OPTIMIZE_OPTION .startsWith(nextWord)) configuration.optimize = parseNoArgument(false); else if (ConfigurationConstants.OPTIMIZATION_PASSES .startsWith(nextWord)) configuration.optimizationPasses = parseIntegerArgument(); else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, true, false, false, false, configuration.optimizations); - else if (ConfigurationConstants.ASSUME_NO_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoSideEffects = parseClassSpecificationArguments(true, configuration.assumeNoSideEffects); - else if (ConfigurationConstants.ASSUME_NO_EXTERNAL_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoExternalSideEffects = parseClassSpecificationArguments(true, configuration.assumeNoExternalSideEffects); - else if (ConfigurationConstants.ASSUME_NO_ESCAPING_PARAMETERS_OPTION .startsWith(nextWord)) configuration.assumeNoEscapingParameters = parseClassSpecificationArguments(true, configuration.assumeNoEscapingParameters); - else if (ConfigurationConstants.ASSUME_NO_EXTERNAL_RETURN_VALUES_OPTION .startsWith(nextWord)) configuration.assumeNoExternalReturnValues = parseClassSpecificationArguments(true, configuration.assumeNoExternalReturnValues); + else if (ConfigurationConstants.ASSUME_NO_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoSideEffects = parseAssumeClassSpecificationArguments(configuration.assumeNoSideEffects); + else if (ConfigurationConstants.ASSUME_NO_EXTERNAL_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoExternalSideEffects = parseAssumeClassSpecificationArguments(configuration.assumeNoExternalSideEffects); + else if (ConfigurationConstants.ASSUME_NO_ESCAPING_PARAMETERS_OPTION .startsWith(nextWord)) configuration.assumeNoEscapingParameters = parseAssumeClassSpecificationArguments(configuration.assumeNoEscapingParameters); + else if (ConfigurationConstants.ASSUME_NO_EXTERNAL_RETURN_VALUES_OPTION .startsWith(nextWord)) configuration.assumeNoExternalReturnValues = parseAssumeClassSpecificationArguments(configuration.assumeNoExternalReturnValues); + else if (ConfigurationConstants.ASSUME_VALUES_OPTION .startsWith(nextWord)) configuration.assumeValues = parseAssumeClassSpecificationArguments(configuration.assumeValues); else if (ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION .startsWith(nextWord)) configuration.allowAccessModification = parseNoArgument(true); else if (ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.mergeInterfacesAggressively = parseNoArgument(true); @@ -536,6 +537,13 @@ } + /** + * Parses and adds a conditional class specification to keep other classes + * and class members. + * @throws ParseException if the class specification contains a syntax error. + * @throws IOException if an IO error occurs while reading the class + * specification. + */ private List parseIfCondition(List keepClassSpecifications) throws ParseException, IOException { @@ -548,7 +556,7 @@ true); ClassSpecification condition = - parseClassSpecificationArguments(); + parseClassSpecificationArguments(false); // Read the corresponding keep option. if (nextWord == null) @@ -571,6 +579,12 @@ } + /** + * Parses and adds a class specification to keep classes and class members. + * @throws ParseException if the class specification contains a syntax error. + * @throws IOException if an IO error occurs while reading the class + * specification. + */ private List parseKeepClassSpecificationArguments(List keepClassSpecifications, boolean markClasses, boolean markConditionally, @@ -593,6 +607,13 @@ } + /** + * Parses and returns a class specification to keep classes and class + * members. + * @throws ParseException if the class specification contains a syntax error. + * @throws IOException if an IO error occurs while reading the class + * specification. + */ private KeepClassSpecification parseKeepClassSpecificationArguments(boolean markClasses, boolean markConditionally, boolean allowShrinking, @@ -656,7 +677,7 @@ // Read the class configuration. ClassSpecification classSpecification = - parseClassSpecificationArguments(); + parseClassSpecificationArguments(false); // Create and return the keep configuration. return new KeepClassSpecification(markClasses, @@ -671,8 +692,13 @@ } - private List parseClassSpecificationArguments(boolean readFirstWord, - List classSpecifications) + /** + * Parses and adds a class specification for optimization assumptions. + * @throws ParseException if the class specification contains a syntax error. + * @throws IOException if an IO error occurs while reading the class + * specification. + */ + private List parseAssumeClassSpecificationArguments(List classSpecifications) throws ParseException, IOException { // Create a new List if necessary. @@ -681,28 +707,33 @@ classSpecifications = new ArrayList(); } - if (readFirstWord) - { - readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD + - "', '" + JavaConstants.ACC_INTERFACE + - "', or '" + JavaConstants.ACC_ENUM + "'", - false, false, true); - } + readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD + + "', '" + JavaConstants.ACC_INTERFACE + + "', or '" + JavaConstants.ACC_ENUM + "'", + false, false, true); // Read and add the class configuration. - classSpecifications.add(parseClassSpecificationArguments()); + classSpecifications.add(parseClassSpecificationArguments(true)); return classSpecifications; } + // Added for compatibility with older versions of ProGuard (see PGD-755). + public ClassSpecification parseClassSpecificationArguments() + throws ParseException, IOException + { + return parseClassSpecificationArguments(false); + } + + /** * Parses and returns a class specification. * @throws ParseException if the class specification contains a syntax error. * @throws IOException if an IO error occurs while reading the class * specification. */ - public ClassSpecification parseClassSpecificationArguments() + public ClassSpecification parseClassSpecificationArguments(boolean allowValues) throws ParseException, IOException { // Clear the annotation type. @@ -874,6 +905,7 @@ } parseMemberSpecificationArguments(externalClassName, + allowValues, classSpecification); } } @@ -882,7 +914,14 @@ } + /** + * Parses and adds a class member specification. + * @throws ParseException if the class specification contains a syntax error. + * @throws IOException if an IO error occurs while reading the class + * specification. + */ private void parseMemberSpecificationArguments(String externalClassName, + boolean allowValues, ClassSpecification classSpecification) throws ParseException, IOException { @@ -1072,6 +1111,38 @@ name, descriptor)); } + else if (allowValues && + (ConfigurationConstants.EQUAL_KEYWORD.equals(nextWord) || + ConfigurationConstants.RETURN_KEYWORD.equals(nextWord))) + { + // It's a field with a value. + checkFieldAccessFlags(requiredSetMemberAccessFlags, + requiredUnsetMemberAccessFlags); + + // We already have a field descriptor. + String descriptor = ClassUtil.internalType(type); + + // Read the constant. + Number[] values = parseValues(type, descriptor); + + // Read the separator after the constant. + readNextWord("separator '" + ConfigurationConstants.SEPARATOR_KEYWORD + "'"); + + if (!ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord)) + { + throw new ParseException("Expecting separator '" + ConfigurationConstants.SEPARATOR_KEYWORD + + "' before " + reader.locationDescription()); + } + + // Add the field. + classSpecification.addField( + new MemberValueSpecification(requiredSetMemberAccessFlags, + requiredUnsetMemberAccessFlags, + annotationType, + name, + descriptor, + values)); + } else if (ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD.equals(nextWord)) { // It's a method. @@ -1093,19 +1164,51 @@ // Read the separator after the closing parenthesis. readNextWord("separator '" + ConfigurationConstants.SEPARATOR_KEYWORD + "'"); - if (!ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord)) + if (ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord)) + { + // Add the plain method. + classSpecification.addMethod( + new MemberSpecification(requiredSetMemberAccessFlags, + requiredUnsetMemberAccessFlags, + annotationType, + name, + descriptor)); + } + else if (allowValues && + (ConfigurationConstants.EQUAL_KEYWORD.equals(nextWord) || + ConfigurationConstants.RETURN_KEYWORD.equals(nextWord))) + { + // It's a method with a value. + checkFieldAccessFlags(requiredSetMemberAccessFlags, + requiredUnsetMemberAccessFlags); + + // Read the constant. + Number[] values = parseValues(type, ClassUtil.internalType(type)); + + // Read the separator after the constant. + readNextWord("separator '" + ConfigurationConstants.SEPARATOR_KEYWORD + "'"); + + if (!ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord)) + { + throw new ParseException("Expecting separator '" + ConfigurationConstants.SEPARATOR_KEYWORD + + "' before " + reader.locationDescription()); + } + + // Add the method. + classSpecification.addMethod( + new MemberValueSpecification(requiredSetMemberAccessFlags, + requiredUnsetMemberAccessFlags, + annotationType, + name, + descriptor, + values)); + } + else { throw new ParseException("Expecting separator '" + ConfigurationConstants.SEPARATOR_KEYWORD + "' before " + reader.locationDescription()); - } - // Add the method. - classSpecification.addMethod( - new MemberSpecification(requiredSetMemberAccessFlags, - requiredUnsetMemberAccessFlags, - annotationType, - name, - descriptor)); + } } else { @@ -1119,6 +1222,105 @@ /** + * Reads a value or value range of the given primitive type. + * For example, values "123" or "100..199" of type "int" ("I"). + */ + private Number[] parseValues(String externalType, + String internalType) + throws ParseException, IOException + { + readNextWord(externalType + " constant"); + + int rangeIndex = nextWord.indexOf(ConfigurationConstants.RANGE_KEYWORD); + return rangeIndex >= 0 ? + new Number[] + { + parseValue(externalType, internalType, nextWord.substring(0, rangeIndex)), + parseValue(externalType, internalType, nextWord.substring(rangeIndex + ConfigurationConstants.RANGE_KEYWORD.length())) + } : + new Number[] + { + parseValue(externalType, internalType, nextWord) + }; + } + + + /** + * Parses the given string as a value of the given primitive type. + * For example, value "123" of type "int" ("I"). + * For example, value "true" of type "boolean" ("Z"), returned as 1. + */ + private Number parseValue(String externalType, + String internalType, + String string) + throws ParseException + { + try + { + string = replaceSystemProperties(string); + + switch (internalType.charAt(0)) + { + case ClassConstants.TYPE_BOOLEAN: + { + return parseBoolean(string); + } + case ClassConstants.TYPE_BYTE: + case ClassConstants.TYPE_CHAR: + case ClassConstants.TYPE_SHORT: + case ClassConstants.TYPE_INT: + { + return Integer.decode(string); + } + //case ClassConstants.TYPE_LONG: + //{ + // return Long.decode(string); + //} + //case ClassConstants.TYPE_FLOAT: + //{ + // return Float.valueOf(string); + //} + //case ClassConstants.TYPE_DOUBLE: + //{ + // return Double.valueOf(string); + //} + default: + { + throw new ParseException("Can't handle '" + externalType + + "' constant " + reader.locationDescription()); + } + } + } + catch (NumberFormatException e) + { + throw new ParseException("Can't parse " + externalType + + " constant " + reader.locationDescription()); + } + } + + + /** + * Parses the given boolean string as an integer (0 or 1). + */ + private Integer parseBoolean(String string) + throws ParseException + { + if (ConfigurationConstants.FALSE_KEYWORD.equals(nextWord)) + { + return Integer.valueOf(0); + } + else if (ConfigurationConstants.TRUE_KEYWORD.equals(nextWord)) + { + return Integer.valueOf(1); + } + else + { + throw new ParseException("Unknown boolean constant " + reader.locationDescription()); + } + } + + + /** * Reads a comma-separated list of Lists of java identifiers or of file * names. */ @@ -1488,9 +1690,8 @@ if (!allowGenerics && containsGenerics(nextWord)) { - throw new ParseException("Use of generics not allowed for " + - expectedDescription + - " at " + reader.locationDescription()); + throw new ParseException("Generics are not allowed (erased) in " + expectedDescription + + " " + reader.locationDescription()); } } @@ -1499,16 +1700,16 @@ * Returns whether the given word is a valid Java identifier. * Wildcard characters are accepted. */ - private boolean isJavaIdentifier(String aWord) + private boolean isJavaIdentifier(String word) { - if (aWord.length() == 0) + if (word.length() == 0) { return false; } - for (int index = 0; index < aWord.length(); index++) + for (int index = 0; index < word.length(); index++) { - char c = aWord.charAt(index); + char c = word.charAt(index); if (!(Character.isJavaIdentifierPart(c) || c == '.' || c == '[' || @@ -1529,40 +1730,43 @@ } - private boolean containsGenerics(String aWord) - { - return containsGenerics(aWord, 0); - } - - /** * Returns whether the given word contains angle brackets around * a non-digit string. */ - private boolean containsGenerics(String aWord, int startIndex) + private boolean containsGenerics(String word) { - int openIndex = aWord.indexOf('<', startIndex); - if (openIndex < 0) - { - return false; - } + int index = 0; - int closeIndex = aWord.indexOf('>', startIndex + openIndex + 1); - if (closeIndex < 0) + while (true) { - return false; - } + // Can we find an opening angular bracket? + int openIndex = word.indexOf(ClassConstants.TYPE_GENERIC_START, index); + if (openIndex < 0) + { + return false; + } - try - { - Integer.parseInt(aWord.substring(openIndex + 1, closeIndex)); - } - catch (NumberFormatException e) - { - return true; - } + // Can we find a corresponding closing angular bracket? + int closeIndex = word.indexOf(ClassConstants.TYPE_GENERIC_END, openIndex + 1); + if (closeIndex < 0) + { + return false; + } - return containsGenerics(aWord,closeIndex); + try + { + // Is it just a reference to a wildcard? + Integer.parseInt(word.substring(openIndex + 1, closeIndex)); + } + catch (NumberFormatException e) + { + // It's not; it's really a generic type. + return true; + } + + index = closeIndex + 1; + } } diff -Nru proguard-6.0.3/core/src/proguard/ConfigurationWriter.java proguard-6.2.0/core/src/proguard/ConfigurationWriter.java --- proguard-6.0.3/core/src/proguard/ConfigurationWriter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ConfigurationWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -22,7 +22,7 @@ import proguard.classfile.ClassConstants; import proguard.classfile.util.ClassUtil; -import proguard.util.ListUtil; +import proguard.util.*; import java.io.*; import java.net.*; @@ -52,24 +52,13 @@ */ public ConfigurationWriter(File configurationFile) throws IOException { - this(new PrintWriter( - new OutputStreamWriter( - new FileOutputStream(configurationFile), "UTF-8"))); + this(PrintWriterUtil.createPrintWriterOut(configurationFile)); baseDir = configurationFile.getParentFile(); } /** - * Creates a new ConfigurationWriter for the given OutputStream. - */ - public ConfigurationWriter(OutputStream outputStream) throws IOException - { - this(new PrintWriter(outputStream)); - } - - - /** * Creates a new ConfigurationWriter for the given PrintWriter. */ public ConfigurationWriter(PrintWriter writer) throws IOException @@ -168,6 +157,7 @@ writeOptions(ConfigurationConstants.ASSUME_NO_EXTERNAL_SIDE_EFFECTS_OPTION, configuration.assumeNoExternalSideEffects); writeOptions(ConfigurationConstants.ASSUME_NO_ESCAPING_PARAMETERS_OPTION, configuration.assumeNoEscapingParameters); writeOptions(ConfigurationConstants.ASSUME_NO_EXTERNAL_RETURN_VALUES_OPTION, configuration.assumeNoExternalReturnValues); + writeOptions(ConfigurationConstants.ASSUME_VALUES_OPTION, configuration.assumeValues); if (writer.checkError()) @@ -589,6 +579,9 @@ name == null ? ConfigurationConstants.ANY_CLASS_MEMBER_KEYWORD : name, descriptor)); + writeValueAssignment(ConfigurationConstants.EQUAL_KEYWORD, + memberSpecification); + writer.println(ConfigurationConstants.SEPARATOR_KEYWORD); } } @@ -632,12 +625,56 @@ name == null ? ConfigurationConstants.ANY_CLASS_MEMBER_KEYWORD : name, descriptor)); + writeValueAssignment(ConfigurationConstants.RETURN_KEYWORD, + memberSpecification); + writer.println(ConfigurationConstants.SEPARATOR_KEYWORD); } } } + private void writeValueAssignment(String assignmentKeyword, + MemberSpecification memberSpecification) + { + if (memberSpecification instanceof MemberValueSpecification) + { + MemberValueSpecification memberValueSpecification = + (MemberValueSpecification)memberSpecification; + + Number[] values = memberValueSpecification.values; + if (values != null) + { + writer.print(' '); + writer.print(assignmentKeyword); + writer.print(' '); + + // Write the first value. + // Is it a boolean? + String descriptor = memberSpecification.descriptor; + if (descriptor != null && + ClassUtil.internalMethodReturnType(descriptor).equals("" + ClassConstants.TYPE_BOOLEAN)) + { + // It's a boolean (represented as an integer). + writer.print(values[0].intValue() != 0); + } + else + { + // It's a number. + writer.print(values[0]); + } + + // Write the second value of the range, if any. + if (values.length > 1) + { + writer.print(ConfigurationConstants.RANGE_KEYWORD); + writer.print(values[1]); + } + } + } + } + + /** * Returns a list with external versions of the given list of internal * class names. @@ -699,7 +736,8 @@ /** * A main method for testing configuration writing. */ - public static void main(String[] args) { + public static void main(String[] args) + { try { ConfigurationWriter writer = new ConfigurationWriter(new File(args[0])); diff -Nru proguard-6.0.3/core/src/proguard/DataEntryReaderFactory.java proguard-6.2.0/core/src/proguard/DataEntryReaderFactory.java --- proguard-6.0.3/core/src/proguard/DataEntryReaderFactory.java 2018-04-08 21:39:48.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/DataEntryReaderFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/DataEntryWriterFactory.java proguard-6.2.0/core/src/proguard/DataEntryWriterFactory.java --- proguard-6.0.3/core/src/proguard/DataEntryWriterFactory.java 2018-04-08 21:17:53.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/DataEntryWriterFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/DescriptorKeepChecker.java proguard-6.2.0/core/src/proguard/DescriptorKeepChecker.java --- proguard-6.0.3/core/src/proguard/DescriptorKeepChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/DescriptorKeepChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/DuplicateClassPrinter.java proguard-6.2.0/core/src/proguard/DuplicateClassPrinter.java --- proguard-6.0.3/core/src/proguard/DuplicateClassPrinter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/DuplicateClassPrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/AssumeClassSpecificationVisitorFactory.java proguard-6.2.0/core/src/proguard/evaluation/AssumeClassSpecificationVisitorFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/AssumeClassSpecificationVisitorFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/AssumeClassSpecificationVisitorFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,150 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.evaluation; + +import proguard.*; +import proguard.classfile.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; +import proguard.evaluation.value.*; +import proguard.optimize.OptimizationInfoMemberFilter; +import proguard.optimize.info.*; + +import java.util.*; + +/** + * This factory creates visitors to efficiently travel to specified classes and + * class members and set specified values on them. + * + * @author Eric Lafortune + */ +public class AssumeClassSpecificationVisitorFactory +extends ClassSpecificationVisitorFactory +{ + private final ValueFactory valueFactory; + + + public AssumeClassSpecificationVisitorFactory(ValueFactory valueFactory) + { + this.valueFactory = valueFactory; + } + + + // Overriding implementations for ClassSpecificationVisitorFactory. + + protected ClassVisitor createNonTestingClassVisitor(MemberSpecification memberSpecification, + boolean isField, + MemberVisitor memberVisitor, + AttributeVisitor attributeVisitor, + List variableStringMatchers) + { + if (memberSpecification instanceof MemberValueSpecification) + { + // We can only know the value of this member specification at this + // point. + MemberValueSpecification memberValueSpecification = + (MemberValueSpecification)memberSpecification; + + Number[] values = memberValueSpecification.values; + if (values != null) + { + // Convert the Number array to a Value. + Value value = value(values); + + // We're adding a member visitor to set the value. + memberVisitor = + new MultiMemberVisitor( + memberVisitor, + new OptimizationInfoMemberFilter( + new MyMemberValueSetter(value))); + } + } + + return super.createNonTestingClassVisitor(memberSpecification, + isField, + memberVisitor, + attributeVisitor, + variableStringMatchers); + } + + + // Small utility methods. + + private Value value(Number[] values) + { + return values.length == 1 ? + valueFactory.createIntegerValue(values[0].intValue()) : + valueFactory.createIntegerValue(values[0].intValue(), + values[1].intValue()); + } + + + /** + * This MemberVisitor sets a given value on the optimization info of the + * members that it visits. + */ + private static class MyMemberValueSetter + implements MemberVisitor + { + private final Value value; + + + public MyMemberValueSetter(Value value) + { + this.value = value; + } + + + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + FieldOptimizationInfo + .getFieldOptimizationInfo(programField) + .setValue(value); + } + + + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + MethodOptimizationInfo + .getMethodOptimizationInfo(programMethod) + .setReturnValue(value); + } + + + public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) + { + FieldOptimizationInfo + .getFieldOptimizationInfo(libraryField) + .setValue(value); + } + + + public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) + { + MethodOptimizationInfo + .getMethodOptimizationInfo(libraryMethod) + .setReturnValue(value); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/evaluation/BasicBranchUnit.java proguard-6.2.0/core/src/proguard/evaluation/BasicBranchUnit.java --- proguard-6.0.3/core/src/proguard/evaluation/BasicBranchUnit.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/BasicBranchUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/BasicInvocationUnit.java proguard-6.2.0/core/src/proguard/evaluation/BasicInvocationUnit.java --- proguard-6.0.3/core/src/proguard/evaluation/BasicInvocationUnit.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/BasicInvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/BranchUnit.java proguard-6.2.0/core/src/proguard/evaluation/BranchUnit.java --- proguard-6.0.3/core/src/proguard/evaluation/BranchUnit.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/BranchUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/ClassConstantValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/ClassConstantValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/ClassConstantValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/ClassConstantValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/ConstantValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/ConstantValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/ConstantValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/ConstantValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -23,7 +23,7 @@ import proguard.classfile.*; import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; -import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.util.*; import proguard.evaluation.value.*; /** @@ -98,6 +98,25 @@ false); } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + String type = ClassUtil.internalMethodReturnType(dynamicConstant.getType(clazz)); + + // Is the method returning a class type? + Clazz[] referencedClasses = dynamicConstant.referencedClasses; + Clazz referencedClass = + referencedClasses != null && + referencedClasses.length > 0 && + ClassUtil.isInternalClassType(type) ? + referencedClasses[referencedClasses.length - 1] : + null; + + value = valueFactory.createValue(type, + referencedClass, + true, + true); + } + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) { value = valueFactory.createReferenceValue(ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_HANDLE, diff -Nru proguard-6.0.3/core/src/proguard/evaluation/InvocationUnit.java proguard-6.2.0/core/src/proguard/evaluation/InvocationUnit.java --- proguard-6.0.3/core/src/proguard/evaluation/InvocationUnit.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/InvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/Processor.java proguard-6.2.0/core/src/proguard/evaluation/Processor.java --- proguard-6.0.3/core/src/proguard/evaluation/Processor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/Processor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/SimplifiedInvocationUnit.java proguard-6.2.0/core/src/proguard/evaluation/SimplifiedInvocationUnit.java --- proguard-6.0.3/core/src/proguard/evaluation/SimplifiedInvocationUnit.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/SimplifiedInvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -184,11 +184,7 @@ String type = methodrefConstant.getType(clazz); // Count the number of parameters. - int parameterCount = ClassUtil.internalMethodParameterCount(type); - if (!isStatic) - { - parameterCount++; - } + int parameterCount = ClassUtil.internalMethodParameterCount(type, isStatic); // Pop the parameters and the class reference, in reverse order. for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--) @@ -210,11 +206,7 @@ String type = invokeDynamicConstant.getType(clazz); // Count the number of parameters. - int parameterCount = ClassUtil.internalMethodParameterCount(type); - if (!isStatic) - { - parameterCount++; - } + int parameterCount = ClassUtil.internalMethodParameterCount(type, isStatic); // Pop the parameters and the class reference, in reverse order. for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--) diff -Nru proguard-6.0.3/core/src/proguard/evaluation/Stack.java proguard-6.2.0/core/src/proguard/evaluation/Stack.java --- proguard-6.0.3/core/src/proguard/evaluation/Stack.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/Stack.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/TracedStack.java proguard-6.2.0/core/src/proguard/evaluation/TracedStack.java --- proguard-6.0.3/core/src/proguard/evaluation/TracedStack.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/TracedStack.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/TracedVariables.java proguard-6.2.0/core/src/proguard/evaluation/TracedVariables.java --- proguard-6.0.3/core/src/proguard/evaluation/TracedVariables.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/TracedVariables.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ArrayReferenceValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/ArrayReferenceValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ArrayReferenceValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ArrayReferenceValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ArrayReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ArrayReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ArrayReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ArrayReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/BasicValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/BasicValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/BasicValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/BasicValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -77,6 +77,12 @@ { return createIntegerValue(); } + + + public IntegerValue createIntegerValue(int min, int max) + { + return createIntegerValue(); + } public LongValue createLongValue() diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/Category1Value.java proguard-6.2.0/core/src/proguard/evaluation/value/Category1Value.java --- proguard-6.0.3/core/src/proguard/evaluation/value/Category1Value.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/Category1Value.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/Category2Value.java proguard-6.2.0/core/src/proguard/evaluation/value/Category2Value.java --- proguard-6.0.3/core/src/proguard/evaluation/value/Category2Value.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/Category2Value.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ComparisonValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ComparisonValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ComparisonValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ComparisonValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/CompositeDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/CompositeDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/CompositeDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/CompositeDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/CompositeFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/CompositeFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/CompositeFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/CompositeFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/CompositeIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/CompositeIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/CompositeIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/CompositeIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/CompositeLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/CompositeLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/CompositeLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/CompositeLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedByteValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedByteValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedByteValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedByteValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedCharacterValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedCharacterValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedCharacterValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedCharacterValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedShortValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedShortValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ConvertedShortValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ConvertedShortValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/DetailedArrayReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/DetailedArrayReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/DetailedArrayReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/DetailedArrayReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/DetailedArrayValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/DetailedArrayValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/DetailedArrayValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/DetailedArrayValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/DoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/DoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/DoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/DoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/FloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/FloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/FloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/FloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IdentifiedValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IdentifiedValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/InitialValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/InitialValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/InitialValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/InitialValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/InstructionOffsetValue.java proguard-6.2.0/core/src/proguard/evaluation/value/InstructionOffsetValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/InstructionOffsetValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/InstructionOffsetValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/IntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/IntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/IntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/IntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -976,6 +976,225 @@ { return -lessThan(other); } + + + // Similar binary methods, but this time with range arguments. + + /** + * Returns the generalization of this IntegerValue and the given other + * RangeIntegerValue. + */ + public IntegerValue generalize(RangeIntegerValue other) + { + return generalize((IntegerValue)other); + } + + + /** + * Returns the sum of this IntegerValue and the given RangeIntegerValue. + */ + public IntegerValue add(RangeIntegerValue other) + { + return add((IntegerValue)other); + } + + /** + * Returns the difference of this IntegerValue and the given RangeIntegerValue. + */ + public IntegerValue subtract(RangeIntegerValue other) + { + return subtract((IntegerValue)other); + } + + /** + * Returns the difference of the given RangeIntegerValue and this IntegerValue. + */ + public IntegerValue subtractFrom(RangeIntegerValue other) + { + return subtractFrom((IntegerValue)other); + } + + /** + * Returns the product of this IntegerValue and the given RangeIntegerValue. + */ + public IntegerValue multiply(RangeIntegerValue other) + { + return multiply((IntegerValue)other); + } + + /** + * Returns the quotient of this IntegerValue and the given + * RangeIntegerValue. + */ + public IntegerValue divide(RangeIntegerValue other) + { + return divide((IntegerValue)other); + } + + /** + * Returns the quotient of the given RangeIntegerValue and this + * IntegerValue. + */ + public IntegerValue divideOf(RangeIntegerValue other) + { + return divideOf((IntegerValue)other); + } + + /** + * Returns the remainder of this IntegerValue divided by the given + * RangeIntegerValue. + */ + public IntegerValue remainder(RangeIntegerValue other) + { + return remainder((IntegerValue)other); + } + + /** + * Returns the remainder of the given RangeIntegerValue divided by this + * IntegerValue. + */ + public IntegerValue remainderOf(RangeIntegerValue other) + { + return remainderOf((IntegerValue)other); + } + + /** + * Returns this IntegerValue, shifted left by the given RangeIntegerValue. + */ + public IntegerValue shiftLeft(RangeIntegerValue other) + { + return shiftLeft((IntegerValue)other); + } + + /** + * Returns this IntegerValue, shifted right by the given RangeIntegerValue. + */ + public IntegerValue shiftRight(RangeIntegerValue other) + { + return shiftRight((IntegerValue)other); + } + + /** + * Returns this unsigned IntegerValue, shifted right by the given + * RangeIntegerValue. + */ + public IntegerValue unsignedShiftRight(RangeIntegerValue other) + { + return unsignedShiftRight((IntegerValue)other); + } + + /** + * Returns the given RangeIntegerValue, shifted left by this IntegerValue. + */ + public IntegerValue shiftLeftOf(RangeIntegerValue other) + { + return shiftLeftOf((IntegerValue)other); + } + + /** + * Returns the given RangeIntegerValue, shifted right by this IntegerValue. + */ + public IntegerValue shiftRightOf(RangeIntegerValue other) + { + return shiftRightOf((IntegerValue)other); + } + + /** + * Returns the given unsigned RangeIntegerValue, shifted right by this + * IntegerValue. + */ + public IntegerValue unsignedShiftRightOf(RangeIntegerValue other) + { + return unsignedShiftRightOf((IntegerValue)other); + } + + /** + * Returns the logical and of this IntegerValue and the given + * RangeIntegerValue. + */ + public IntegerValue and(RangeIntegerValue other) + { + return and((IntegerValue)other); + } + + /** + * Returns the logical or of this IntegerValue and the given + * RangeIntegerValue. + */ + public IntegerValue or(RangeIntegerValue other) + { + return or((IntegerValue)other); + } + + /** + * Returns the logical xor of this IntegerValue and the given + * RangeIntegerValue. + */ + public IntegerValue xor(RangeIntegerValue other) + { + return xor((IntegerValue)other); + } + + /** + * Returns whether this IntegerValue and the given RangeIntegerValue are + * equal: NEVER, MAYBE, or ALWAYS. + */ + public int equal(RangeIntegerValue other) + { + return equal((IntegerValue)other); + } + + /** + * Returns whether this IntegerValue is less than the given + * RangeIntegerValue: NEVER, MAYBE, or + * ALWAYS. + */ + public int lessThan(RangeIntegerValue other) + { + return lessThan((IntegerValue)other); + } + + /** + * Returns whether this IntegerValue is less than or equal to the given + * RangeIntegerValue: NEVER, MAYBE, or + * ALWAYS. + */ + public int lessThanOrEqual(RangeIntegerValue other) + { + return lessThanOrEqual((IntegerValue)other); + } + + + // Derived binary methods. + + /** + * Returns whether this IntegerValue and the given RangeIntegerValue are + * different: NEVER, MAYBE, or ALWAYS. + */ + public final int notEqual(RangeIntegerValue other) + { + return -equal(other); + } + + /** + * Returns whether this IntegerValue is greater than the given + * RangeIntegerValue: NEVER, MAYBE, or + * ALWAYS. + */ + public final int greaterThan(RangeIntegerValue other) + { + return -lessThanOrEqual(other); + } + + /** + * Returns whether this IntegerValue is greater than or equal to the given + * RangeIntegerValue: NEVER, MAYBE, or + * ALWAYS. + */ + public final int greaterThanOrEqual(RangeIntegerValue other) + { + return -lessThan(other); + } // Implementations for Value. diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/LongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/LongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/LongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/LongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -549,6 +549,6 @@ public final String internalType() { - return String.valueOf(ClassConstants.TYPE_INT); + return String.valueOf(ClassConstants.TYPE_LONG); } } diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/NegatedDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/NegatedDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/NegatedDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/NegatedDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/NegatedFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/NegatedFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/NegatedFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/NegatedFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/NegatedIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/NegatedIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/NegatedIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/NegatedIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/NegatedLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/NegatedLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/NegatedLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/NegatedLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ParticularDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ParticularDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ParticularDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ParticularDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ParticularFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ParticularFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ParticularFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ParticularFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ParticularIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ParticularIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ParticularIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ParticularIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -23,6 +23,18 @@ /** * This IntegerValue represents a particular integer value. * + * This class handles interactions with: + * - ParticularIntegerValue + * + * It reverses and delegates interactions with: + * - RangeIntegerValue + * - IntegerValue (in general) + * + * It notably doesn't handle interactions with: + * - UnknownInteger + * - RangeIntegerValue + * - SpecificInteger (in general) + * * @author Eric Lafortune */ final class ParticularIntegerValue extends SpecificIntegerValue @@ -352,6 +364,118 @@ } + // Implementations of binary methods of RangeIntegerValue. + + public IntegerValue generalize(RangeIntegerValue other) + { + return other.generalize(this); + } + + public IntegerValue add(RangeIntegerValue other) + { + return other.add(this); + } + + public IntegerValue subtract(RangeIntegerValue other) + { + return other.subtractFrom(this); + } + + public IntegerValue subtractFrom(RangeIntegerValue other) + { + return other.subtract(this); + } + + public IntegerValue multiply(RangeIntegerValue other) + { + return other.multiply(this); + } + + public IntegerValue divide(RangeIntegerValue other) + throws ArithmeticException + { + return other.divideOf(this); + } + + public IntegerValue divideOf(RangeIntegerValue other) + throws ArithmeticException + { + return other.divide(this); + } + + public IntegerValue remainder(RangeIntegerValue other) + throws ArithmeticException + { + return other.remainderOf(this); + } + + public IntegerValue remainderOf(RangeIntegerValue other) + throws ArithmeticException + { + return other.remainder(this); + } + + public IntegerValue shiftLeft(RangeIntegerValue other) + { + return other.shiftLeftOf(this); + } + + public IntegerValue shiftLeftOf(RangeIntegerValue other) + { + return other.shiftLeft(this); + } + + public IntegerValue shiftRight(RangeIntegerValue other) + { + return other.shiftRightOf(this); + } + + public IntegerValue shiftRightOf(RangeIntegerValue other) + { + return other.shiftRight(this); + } + + public IntegerValue unsignedShiftRight(RangeIntegerValue other) + { + return other.unsignedShiftRightOf(this); + } + + public IntegerValue unsignedShiftRightOf(RangeIntegerValue other) + { + return other.unsignedShiftRight(this); + } + + public IntegerValue and(RangeIntegerValue other) + { + return other.and(this); + } + + public IntegerValue or(RangeIntegerValue other) + { + return other.or(this); + } + + public IntegerValue xor(RangeIntegerValue other) + { + return other.xor(this); + } + + public int equal(RangeIntegerValue other) + { + return other.equal(this); + } + + public int lessThan(RangeIntegerValue other) + { + return other.greaterThan(this); + } + + public int lessThanOrEqual(RangeIntegerValue other) + { + return other.greaterThanOrEqual(this); + } + + // Implementations for Value. public boolean isParticular() diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ParticularLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ParticularLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ParticularLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ParticularLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ParticularValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/ParticularValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ParticularValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ParticularValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/PrimitiveTypedReferenceValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/PrimitiveTypedReferenceValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/PrimitiveTypedReferenceValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/PrimitiveTypedReferenceValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/RangeIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/RangeIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/RangeIntegerValue.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/RangeIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,737 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.evaluation.value; + +/** + * This IntegerValue represents a known range of integer values. + * It currently is not a SpecificIntegerValue, so it doesn't have + * a particular value nor an identifier. + * + * This class handles interactions with: + * - ParticularIntegerValue + * - RangeIntegerValue + * + * It reverses and delegates interactions with: + * - IntegerValue (in general) + * + * It notably doesn't handle interactions with: + * - UnknownInteger + * - SpecificInteger (in general) + * + * @author Eric Lafortune + */ +public final class RangeIntegerValue extends IntegerValue +{ + private final int min; + private final int max; + + + /** + * Creates a new range of integer values. + */ + public RangeIntegerValue(int min, int max) + { + this.min = min; + this.max = max; + } + + + // Implementations for IntegerValue. + + public int value() + { + return min; + } + + + // Implementations of unary methods of IntegerValue. + + public IntegerValue negate() + { + return new RangeIntegerValue( + min == Integer.MIN_VALUE ? Integer.MIN_VALUE : + -max, + -min); + } + + public IntegerValue convertToByte() + { + return min >= Byte.MIN_VALUE && + max <= Byte.MAX_VALUE ? + this : + RangeValueFactory.INTEGER_VALUE_BYTE; + } + + public IntegerValue convertToCharacter() + { + return min >= Character.MIN_VALUE && + max <= Character.MAX_VALUE ? + this : + RangeValueFactory.INTEGER_VALUE_CHAR; + } + + public IntegerValue convertToShort() + { + return min >= Short.MIN_VALUE && + max <= Short.MAX_VALUE ? + this : + RangeValueFactory.INTEGER_VALUE_SHORT; + } + + public LongValue convertToLong() + { + return BasicValueFactory.LONG_VALUE; + } + + public FloatValue convertToFloat() + { + return BasicValueFactory.FLOAT_VALUE; + } + + public DoubleValue convertToDouble() + { + return BasicValueFactory.DOUBLE_VALUE; + } + + + // Implementations of binary methods of IntegerValue. + + public IntegerValue generalize(IntegerValue other) + { + return other.generalize(this); + } + + public IntegerValue add(IntegerValue other) + { + return other.add(this); + } + + public IntegerValue subtract(IntegerValue other) + { + return other.subtractFrom(this); + } + + public IntegerValue subtractFrom(IntegerValue other) + { + return other.subtract(this); + } + + public IntegerValue multiply(IntegerValue other) + { + return other.multiply(this); + } + + public IntegerValue divide(IntegerValue other) + throws ArithmeticException + { + return other.divideOf(this); + } + + public IntegerValue divideOf(IntegerValue other) + throws ArithmeticException + { + return other.divide(this); + } + + public IntegerValue remainder(IntegerValue other) + throws ArithmeticException + { + return other.remainderOf(this); + } + + public IntegerValue remainderOf(IntegerValue other) + throws ArithmeticException + { + return other.remainder(this); + } + + public IntegerValue shiftLeft(IntegerValue other) + { + return other.shiftLeftOf(this); + } + + public IntegerValue shiftLeftOf(IntegerValue other) + { + return other.shiftLeft(this); + } + + public IntegerValue shiftRight(IntegerValue other) + { + return other.shiftRightOf(this); + } + + public IntegerValue shiftRightOf(IntegerValue other) + { + return other.shiftRight(this); + } + + public IntegerValue unsignedShiftRight(IntegerValue other) + { + return other.unsignedShiftRightOf(this); + } + + public IntegerValue unsignedShiftRightOf(IntegerValue other) + { + return other.unsignedShiftRight(this); + } + + public LongValue shiftLeftOf(LongValue other) + { + return other.shiftLeft(this); + } + + public LongValue shiftRightOf(LongValue other) + { + return other.shiftRight(this); + } + + public LongValue unsignedShiftRightOf(LongValue other) + { + return other.unsignedShiftRight(this); + } + + public IntegerValue and(IntegerValue other) + { + return other.and(this); + } + + public IntegerValue or(IntegerValue other) + { + return other.or(this); + } + + public IntegerValue xor(IntegerValue other) + { + return other.xor(this); + } + + public int equal(IntegerValue other) + { + return other.equal(this); + } + + public int lessThan(IntegerValue other) + { + return other.greaterThan(this); + } + + public int lessThanOrEqual(IntegerValue other) + { + return other.greaterThanOrEqual(this); + } + + + // Implementations of binary IntegerValue methods with ParticularIntegerValue + // arguments. + + public IntegerValue generalize(ParticularIntegerValue other) + { + // Extend the range if necessary. + int value = other.value(); + return value < min ? new RangeIntegerValue(value, max) : + value > max ? new RangeIntegerValue(min, value) : + this; + } + + public IntegerValue add(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? this : + // Check for overflow. + (value > 0 ? max + value < max : + min + value > min) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + new RangeIntegerValue(min + value, max + value); + } + + public IntegerValue subtract(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? this : + // Check for overflow. + (value < 0 ? max - value < max : + min - value > min) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + new RangeIntegerValue(min - value, max - value); + } + + public IntegerValue subtractFrom(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check for overflow. + (long)value - (long)max != (long)(value - max) || + (long)value - (long)min != (long)(value - min) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + new RangeIntegerValue(value - max, value - min); + } + + public IntegerValue multiply(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? other : + value == 1 ? this : + // Check for overflow. + (long)min * (long)value != (long)(min * value) || + (long)max * (long)value != (long)(max * value) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + // Check if the interval is inverted. + value < 0 ? + new RangeIntegerValue(max * value, min * value) : + new RangeIntegerValue(min * value, max * value); + } + + public IntegerValue divide(ParticularIntegerValue other) + throws ArithmeticException + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? BasicValueFactory.INTEGER_VALUE : + value == 1 ? this : + // Check for overflow. + (long)min / (long)value != (long)(min / value) || + (long)max / (long)value != (long)(max / value) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + // Check if the interval is inverted. + value < 0 ? + new RangeIntegerValue(max / value, min / value) : + new RangeIntegerValue(min / value, max / value); + } + + public IntegerValue divideOf(ParticularIntegerValue other) + throws ArithmeticException + { + int value = other.value(); + return + // Check simple cases. + min <= 0 && + max >= 0 ? BasicValueFactory.INTEGER_VALUE : + // Check for overflow. + (long)value / (long)min != (long)(value / min) || + (long)value / (long)max != (long)(value / max) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + // Check if the interval is inverted. + value < 0 ^ min < 0 ? + new RangeIntegerValue(value / min, value / max) : + new RangeIntegerValue(value / max, value / min); + } + + public IntegerValue remainder(ParticularIntegerValue other) + throws ArithmeticException + { + int value = other.value(); + return + // Check difficult cases. + value <= 0 || + min < 0 ? BasicValueFactory.INTEGER_VALUE : + // Check simple cases. + max < value ? this : + new RangeIntegerValue(0, value - 1); + } + + public IntegerValue remainderOf(ParticularIntegerValue other) + throws ArithmeticException + { + int value = other.value(); + return + // Check difficult cases. + value < 0 || + min <= 0 ? BasicValueFactory.INTEGER_VALUE : + // Check simple cases. + value < min ? other : + value < max ? new RangeIntegerValue(0, value) : + new RangeIntegerValue(0, max - 1); + } + + public IntegerValue shiftLeft(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + (value & 0x1f) == 0 ? this : + // Check for overflow. + (long)min << value != (long)(min << value) || + (long)max << value != (long)(max << value) ? + BasicValueFactory.INTEGER_VALUE : + new RangeIntegerValue(min << value, max << value); + } + + public IntegerValue shiftRight(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + (value & 0x1f) == 0 ? this : + new RangeIntegerValue(min >> value, max >> value); + } + + public IntegerValue unsignedShiftRight(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + (value & 0x1f) == 0 ? this : + min < 0 ? + max > 0 ? + // The negative-to-positive case. + new RangeIntegerValue(0, Integer.MIN_VALUE >>> value) : + // The all-negative case. + new RangeIntegerValue(max >>> value, min >>> value) : + // The all-positive case. + new RangeIntegerValue(min >>> value, max >>> value); + } + + public IntegerValue shiftLeftOf(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? other : + // Check for overflow. + min < 0 || + max >= 32 || + (long)value << max != (long)(value << max) ? + BasicValueFactory.INTEGER_VALUE : + value < 0 ? + new RangeIntegerValue(value << max, value << min) : + new RangeIntegerValue(value << min, value << max); + } + + public IntegerValue shiftRightOf(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? other : + // Check for overflow. + min < 0 || + max >= 32 ? + BasicValueFactory.INTEGER_VALUE : + value < 0 ? + new RangeIntegerValue(value >> min, value >> max) : + new RangeIntegerValue(value >> max, value >> min); + } + + public IntegerValue unsignedShiftRightOf(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? other : + // Check for overflow. + min < 0 || + max >= 32 ? + BasicValueFactory.INTEGER_VALUE : + new RangeIntegerValue(value >>> max, value >>> min); + } + + public LongValue shiftLeftOf(ParticularLongValue other) + { + long value = other.value(); + return + // Check simple cases. + value == 0L ? other : + BasicValueFactory.LONG_VALUE; + } + + public LongValue shiftRightOf(ParticularLongValue other) + { + long value = other.value(); + return + // Check simple cases. + value == 0L ? other : + BasicValueFactory.LONG_VALUE; + } + + public LongValue unsignedShiftRightOf(ParticularLongValue other) + { + long value = other.value(); + return + // Check simple cases. + value == 0L ? other : + BasicValueFactory.LONG_VALUE; + } + + public IntegerValue and(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? other : + value == -1 ? this : + // Check difficult cases. + value > 0 ? + new RangeIntegerValue(0, value) : + BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue or(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? this : + value == -1 ? other : + // Check difficult cases. + value < 0 ? + new RangeIntegerValue(value, -1) : + BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue xor(ParticularIntegerValue other) + { + int value = other.value(); + return + // Check simple cases. + value == 0 ? this : + BasicValueFactory.INTEGER_VALUE; + } + + public int equal(ParticularIntegerValue other) + { + int value = other.value(); + return + min == value && + max == value ? ALWAYS : + value < min || + value > max ? NEVER : + MAYBE; + } + + public int lessThan(ParticularIntegerValue other) + { + int value = other.value(); + return + max < value ? ALWAYS : + value <= min ? NEVER : + MAYBE; + } + + public int lessThanOrEqual(ParticularIntegerValue other) + { + int value = other.value(); + return + max <= value ? ALWAYS : + value < min ? NEVER : + MAYBE; + } + + + // Implementations of binary IntegerValue methods with RangeIntegerValue + // arguments. + + public IntegerValue generalize(RangeIntegerValue other) + { + // Extend the range if necessary. + return + // Does this range cover the other range? + this.min <= other.min && + this.max >= other.max ? this : + // Does the other range cover this range? + other.min <= this.min && + other.max >= this.max ? other : + // Extend the range. + new RangeIntegerValue(Math.min(this.min, other.min), + Math.max(this.max, other.max)); + } + + public IntegerValue add(RangeIntegerValue other) + { + return + // Check for overflow. + (long)this.min + (long)other.min != (long)(this.min + other.min) || + (long)this.max + (long)other.max != (long)(this.max + other.max) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + new RangeIntegerValue(this.min + other.min, + this.max + other.max); + } + + public IntegerValue subtract(RangeIntegerValue other) + { + return + // Check for overflow. + (long)this.min - (long)other.max != (long)(this.min - other.max) || + (long)this.max - (long)other.min != (long)(this.max - other.min) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + new RangeIntegerValue(this.min - other.max, + this.max - other.min); + } + + public IntegerValue subtractFrom(RangeIntegerValue other) + { + return + // Check for overflow. + (long)other.min - (long)this.max != (long)(other.min - this.max) || + (long)other.max - (long)this.min != (long)(other.max - this.min) ? + BasicValueFactory.INTEGER_VALUE : + // Transform the range. + new RangeIntegerValue(other.min - this.max, + other.max - this.min); + } + + public IntegerValue multiply(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue divide(RangeIntegerValue other) + throws ArithmeticException + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue divideOf(RangeIntegerValue other) + throws ArithmeticException + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue remainder(RangeIntegerValue other) + throws ArithmeticException + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue remainderOf(RangeIntegerValue other) + throws ArithmeticException + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue shiftLeft(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue shiftRight(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue unsignedShiftRight(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue shiftLeftOf(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue shiftRightOf(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue unsignedShiftRightOf(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue and(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue or(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue xor(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public int equal(RangeIntegerValue other) + { + return + this.min == this.max && + this.min == other.min && + this.min == other.max ? ALWAYS : + this.max < other.min || + other.max < this.min ? NEVER : + MAYBE; + } + + public int lessThan(RangeIntegerValue other) + { + return + this.max < other.min ? ALWAYS : + other.max <= this.min ? NEVER : + MAYBE; + } + + public int lessThanOrEqual(RangeIntegerValue other) + { + return + this.max <= other.min ? ALWAYS : + other.max < this.min ? NEVER : + MAYBE; + } + + + // Implementations for Value. + + public boolean isParticular() + { + return min == max; + } + + + // Implementations for Object. + + public boolean equals(Object object) + { + return super.equals(object) && + this.min == ((RangeIntegerValue)object).min && + this.max == ((RangeIntegerValue)object).max; + } + + + public int hashCode() + { + return this.getClass().hashCode() ^ + min ^ + max; + } + + + public String toString() + { + return min + ".." + max; + } +} \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/RangeValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/RangeValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/RangeValueFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/RangeValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.evaluation.value; + +import proguard.classfile.Clazz; + +/** + * This class provides methods to create and reuse Value objects that have + * known ranges. + * + * @author Eric Lafortune + */ +public class RangeValueFactory +extends ParticularValueFactory +implements ValueFactory +{ + // Shared copies of Value objects, to avoid creating a lot of objects. + static final IntegerValue INTEGER_VALUE_BYTE = new RangeIntegerValue(Byte.MIN_VALUE, Byte.MAX_VALUE); + static final IntegerValue INTEGER_VALUE_CHAR = new RangeIntegerValue(Character.MIN_VALUE, Character.MAX_VALUE); + static final IntegerValue INTEGER_VALUE_SHORT = new RangeIntegerValue(Short.MIN_VALUE, Short.MAX_VALUE); + + + /** + * Creates a new RangeValueFactory. + */ + public RangeValueFactory() + { + super(); + } + + + /** + * Creates a new RangeValueFactory that delegates to the given + * value factory for creating reference values. + */ + public RangeValueFactory(ValueFactory referenceValueFactory) + { + super(referenceValueFactory); + } + + + // Implementations for ValueFactory. + + public IntegerValue createIntegerValue(int min, int max) + { + return min == max ? + new ParticularIntegerValue(min) : + new RangeIntegerValue(min, max); + } +} diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/ReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/SpecificDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/SpecificDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/SpecificDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/SpecificDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/SpecificFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/SpecificFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/SpecificFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/SpecificFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/SpecificIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/SpecificIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/SpecificIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/SpecificIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -23,6 +23,16 @@ /** * This IntegerValue represents a specific integer value. * + * This class handles interactions with: + * - RangeIntegerValue + * - SpecificInteger (in general) + * + * It reverses and delegates interactions with: + * - IntegerValue (in general) + * + * It notably doesn't handle interactions with: + * - UnknownInteger + * * @author Eric Lafortune */ abstract class SpecificIntegerValue extends IntegerValue @@ -330,6 +340,119 @@ } + // Implementations of binary IntegerValue methods with RangeIntegerValue + // arguments. + + public IntegerValue generalize(RangeIntegerValue other) + { + return BasicValueFactory.INTEGER_VALUE; + } + + public IntegerValue add(RangeIntegerValue other) + { + return new CompositeIntegerValue(this, CompositeIntegerValue.ADD, other); + } + + public IntegerValue subtract(RangeIntegerValue other) + { + return new CompositeIntegerValue(this, CompositeIntegerValue.SUBTRACT, other); + } + + public IntegerValue subtractFrom(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.SUBTRACT, this); + } + + public IntegerValue multiply(RangeIntegerValue other) + { + return new CompositeIntegerValue(this, CompositeIntegerValue.MULTIPLY, other); + } + + public IntegerValue divide(RangeIntegerValue other) + throws ArithmeticException + { + return new CompositeIntegerValue(this, CompositeIntegerValue.DIVIDE, other); + } + + public IntegerValue divideOf(RangeIntegerValue other) + throws ArithmeticException + { + return new CompositeIntegerValue(other, CompositeIntegerValue.DIVIDE, this); + } + + public IntegerValue remainder(RangeIntegerValue other) + throws ArithmeticException + { + return new CompositeIntegerValue(this, CompositeIntegerValue.REMAINDER, other); + } + + public IntegerValue remainderOf(RangeIntegerValue other) + throws ArithmeticException + { + return new CompositeIntegerValue(other, CompositeIntegerValue.REMAINDER, this); + } + + public IntegerValue shiftLeft(RangeIntegerValue other) + { + return new CompositeIntegerValue(this, CompositeIntegerValue.SHIFT_LEFT, other); + } + + public IntegerValue shiftRight(RangeIntegerValue other) + { + return new CompositeIntegerValue(this, CompositeIntegerValue.SHIFT_RIGHT, other); + } + + public IntegerValue unsignedShiftRight(RangeIntegerValue other) + { + return new CompositeIntegerValue(this, CompositeIntegerValue.UNSIGNED_SHIFT_RIGHT, other); + } + + public IntegerValue shiftLeftOf(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.SHIFT_LEFT, this); + } + + public IntegerValue shiftRightOf(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.SHIFT_RIGHT, this); + } + + public IntegerValue unsignedShiftRightOf(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.UNSIGNED_SHIFT_RIGHT, this); + } + + public IntegerValue and(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.AND, this); + } + + public IntegerValue or(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.OR, this); + } + + public IntegerValue xor(RangeIntegerValue other) + { + return new CompositeIntegerValue(other, CompositeIntegerValue.XOR, this); + } + + public int equal(RangeIntegerValue other) + { + return MAYBE; + } + + public int lessThan(RangeIntegerValue other) + { + return MAYBE; + } + + public int lessThanOrEqual(RangeIntegerValue other) + { + return MAYBE; + } + + // Implementations for Value. public boolean isSpecific() diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/SpecificLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/SpecificLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/SpecificLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/SpecificLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/TopValue.java proguard-6.2.0/core/src/proguard/evaluation/value/TopValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/TopValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/TopValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/TracedReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/TracedReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/TracedReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/TracedReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/TracingValue.java proguard-6.2.0/core/src/proguard/evaluation/value/TracingValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/TracingValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/TracingValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/TypedReferenceValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/TypedReferenceValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/TypedReferenceValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/TypedReferenceValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/TypedReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/TypedReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/TypedReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/TypedReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/UnknownDoubleValue.java proguard-6.2.0/core/src/proguard/evaluation/value/UnknownDoubleValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/UnknownDoubleValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/UnknownDoubleValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/UnknownFloatValue.java proguard-6.2.0/core/src/proguard/evaluation/value/UnknownFloatValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/UnknownFloatValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/UnknownFloatValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/UnknownIntegerValue.java proguard-6.2.0/core/src/proguard/evaluation/value/UnknownIntegerValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/UnknownIntegerValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/UnknownIntegerValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -23,6 +23,9 @@ /** * This class represents a partially evaluated integer value. * + * This class handles interactions with: + * - IntegerValue (in general) + * * @author Eric Lafortune */ public class UnknownIntegerValue extends IntegerValue diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/UnknownLongValue.java proguard-6.2.0/core/src/proguard/evaluation/value/UnknownLongValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/UnknownLongValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/UnknownLongValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/UnknownReferenceValue.java proguard-6.2.0/core/src/proguard/evaluation/value/UnknownReferenceValue.java --- proguard-6.0.3/core/src/proguard/evaluation/value/UnknownReferenceValue.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/UnknownReferenceValue.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/ValueFactory.java proguard-6.2.0/core/src/proguard/evaluation/value/ValueFactory.java --- proguard-6.0.3/core/src/proguard/evaluation/value/ValueFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/ValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -53,6 +53,12 @@ /** + * Creates a new IntegerValue with a given possible range. + */ + public IntegerValue createIntegerValue(int min, int max); + + + /** * Creates a new LongValue with an undefined value. */ public LongValue createLongValue(); diff -Nru proguard-6.0.3/core/src/proguard/evaluation/value/Value.java proguard-6.2.0/core/src/proguard/evaluation/value/Value.java --- proguard-6.0.3/core/src/proguard/evaluation/value/Value.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/value/Value.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/evaluation/Variables.java proguard-6.2.0/core/src/proguard/evaluation/Variables.java --- proguard-6.0.3/core/src/proguard/evaluation/Variables.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/evaluation/Variables.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/FileWordReader.java proguard-6.2.0/core/src/proguard/FileWordReader.java --- proguard-6.0.3/core/src/proguard/FileWordReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/FileWordReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -36,10 +36,12 @@ */ public FileWordReader(File file) throws IOException { - super(new LineNumberReader(new BufferedReader(new FileReader(file))), + super(new LineNumberReader( + new BufferedReader( + new InputStreamReader( + new FileInputStream(file), "UTF-8"))), "file '" + file.getPath() + "'", - file.getParentFile() - ); + file.getParentFile()); } @@ -48,8 +50,10 @@ */ public FileWordReader(URL url) throws IOException { - super(new LineNumberReader(new BufferedReader(new InputStreamReader(url.openStream()))), + super(new LineNumberReader( + new BufferedReader( + new InputStreamReader(url.openStream(), "UTF-8"))), "file '" + url.toString() + "'", - null); + url); } } diff -Nru proguard-6.0.3/core/src/proguard/FullyQualifiedClassNameChecker.java proguard-6.2.0/core/src/proguard/FullyQualifiedClassNameChecker.java --- proguard-6.0.3/core/src/proguard/FullyQualifiedClassNameChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/FullyQualifiedClassNameChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/GetAnnotationChecker.java proguard-6.2.0/core/src/proguard/GetAnnotationChecker.java --- proguard-6.0.3/core/src/proguard/GetAnnotationChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/GetAnnotationChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/GetEnclosingClassChecker.java proguard-6.2.0/core/src/proguard/GetEnclosingClassChecker.java --- proguard-6.0.3/core/src/proguard/GetEnclosingClassChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/GetEnclosingClassChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/GetEnclosingMethodChecker.java proguard-6.2.0/core/src/proguard/GetEnclosingMethodChecker.java --- proguard-6.0.3/core/src/proguard/GetEnclosingMethodChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/GetEnclosingMethodChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/GetSignatureChecker.java proguard-6.2.0/core/src/proguard/GetSignatureChecker.java --- proguard-6.0.3/core/src/proguard/GetSignatureChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/GetSignatureChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/GPL.java proguard-6.2.0/core/src/proguard/GPL.java --- proguard-6.0.3/core/src/proguard/GPL.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/GPL.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -169,6 +169,7 @@ packageName.startsWith("org.eclipse") || packageName.startsWith("org.netbeans") || packageName.startsWith("com.android") || + packageName.startsWith("com.intel") || packageName.startsWith("com.sun.kvem") || packageName.startsWith("net.certiv.proguarddt") || packageName.startsWith("groovy") || diff -Nru proguard-6.0.3/core/src/proguard/Initializer.java proguard-6.2.0/core/src/proguard/Initializer.java --- proguard-6.0.3/core/src/proguard/Initializer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/Initializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -67,7 +67,7 @@ int originalLibraryClassPoolSize = libraryClassPool.size(); // Perform basic checks on the configuration. - WarningPrinter fullyQualifiedClassNameNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter fullyQualifiedClassNameNotePrinter = new WarningPrinter(out, configuration.note); FullyQualifiedClassNameChecker fullyQualifiedClassNameChecker = new FullyQualifiedClassNameChecker(programClassPool, @@ -84,7 +84,7 @@ new ListParser(new NameParser()).parse(configuration.keepAttributes) : new EmptyStringMatcher(); - WarningPrinter getAnnotationNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter getAnnotationNotePrinter = new WarningPrinter(out, configuration.note); if (!keepAttributesMatcher.matches(ClassConstants.ATTR_RuntimeVisibleAnnotations)) { @@ -93,7 +93,7 @@ new GetAnnotationChecker(getAnnotationNotePrinter))); } - WarningPrinter getSignatureNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter getSignatureNotePrinter = new WarningPrinter(out, configuration.note); if (!keepAttributesMatcher.matches(ClassConstants.ATTR_Signature)) { @@ -102,7 +102,7 @@ new GetSignatureChecker(getSignatureNotePrinter))); } - WarningPrinter getEnclosingClassNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter getEnclosingClassNotePrinter = new WarningPrinter(out, configuration.note); if (!keepAttributesMatcher.matches(ClassConstants.ATTR_InnerClasses)) { @@ -111,7 +111,7 @@ new GetEnclosingClassChecker(getEnclosingClassNotePrinter))); } - WarningPrinter getEnclosingMethodNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter getEnclosingMethodNotePrinter = new WarningPrinter(out, configuration.note); if (!keepAttributesMatcher.matches(ClassConstants.ATTR_EnclosingMethod)) { @@ -127,8 +127,8 @@ ClassPool reducedLibraryClassPool = configuration.useUniqueClassMemberNames ? null : new ClassPool(); - WarningPrinter classReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn); - WarningPrinter dependencyWarningPrinter = new WarningPrinter(System.err, configuration.warn); + WarningPrinter classReferenceWarningPrinter = new WarningPrinter(err, configuration.warn); + WarningPrinter dependencyWarningPrinter = new WarningPrinter(err, configuration.warn); // Initialize the superclass hierarchies for program classes. programClassPool.classesAccept( @@ -148,8 +148,8 @@ // Initialize the class references of program class members and // attributes. Note that all superclass hierarchies have to be // initialized for this purpose. - WarningPrinter programMemberReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn); - WarningPrinter libraryMemberReferenceWarningPrinter = new WarningPrinter(System.err, configuration.warn); + WarningPrinter programMemberReferenceWarningPrinter = new WarningPrinter(err, configuration.warn); + WarningPrinter libraryMemberReferenceWarningPrinter = new WarningPrinter(err, configuration.warn); programClassPool.classesAccept( new ClassReferenceInitializer(programClassPool, @@ -162,7 +162,7 @@ if (reducedLibraryClassPool != null) { // Collect the library classes that are directly referenced by - // program classes, without introspection. + // program classes, without reflection. programClassPool.classesAccept( new ReferencedClassVisitor( new LibraryClassFilter( @@ -183,9 +183,9 @@ new AllElementValueVisitor(true, new EnumFieldReferenceInitializer()))); - // Initialize the Class.forName references. - WarningPrinter dynamicClassReferenceNotePrinter = new WarningPrinter(System.out, configuration.note); - WarningPrinter classForNameNotePrinter = new WarningPrinter(System.out, configuration.note); + // Initialize the Class.forName references. + WarningPrinter dynamicClassReferenceNotePrinter = new WarningPrinter(out, configuration.note); + WarningPrinter classForNameNotePrinter = new WarningPrinter(out, configuration.note); programClassPool.classesAccept( new AllMethodVisitor( @@ -199,10 +199,10 @@ createClassNoteExceptionMatcher(configuration.keep, true)))))); // Initialize the WebView.addJavascriptInterface references. - WarningPrinter webViewClassReferenceNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter webViewClassReferenceNotePrinter = new WarningPrinter(out, configuration.note); // Initialize the Class.get[Declared]{Field,Method} references. - WarningPrinter getMemberNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter getMemberNotePrinter = new WarningPrinter(out, configuration.note); programClassPool.classesAccept( new AllMethodVisitor( @@ -285,7 +285,7 @@ libraryClassPool.classesAccept(new StringSharer()); // Check for any unmatched class members. - WarningPrinter classMemberNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter classMemberNotePrinter = new WarningPrinter(out, configuration.note); ClassMemberChecker classMemberChecker = new ClassMemberChecker(programClassPool, @@ -298,14 +298,14 @@ classMemberChecker.checkClassSpecifications(configuration.assumeNoExternalReturnValues); // Check for unkept descriptor classes of kept class members. - WarningPrinter descriptorKeepNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter descriptorKeepNotePrinter = new WarningPrinter(out, configuration.note); new DescriptorKeepChecker(programClassPool, libraryClassPool, descriptorKeepNotePrinter).checkClassSpecifications(configuration.keep); // Check for keep options that only match library classes. - WarningPrinter libraryKeepNotePrinter = new WarningPrinter(System.out, configuration.note); + WarningPrinter libraryKeepNotePrinter = new WarningPrinter(out, configuration.note); new LibraryKeepChecker(programClassPool, libraryClassPool, @@ -315,165 +315,165 @@ int fullyQualifiedNoteCount = fullyQualifiedClassNameNotePrinter.getWarningCount(); if (fullyQualifiedNoteCount > 0) { - System.out.println("Note: there were " + fullyQualifiedNoteCount + - " references to unknown classes."); - System.out.println(" You should check your configuration for typos."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass)"); + out.println("Note: there were " + fullyQualifiedNoteCount + + " references to unknown classes."); + out.println(" You should check your configuration for typos."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass)"); } int classMemberNoteCount = classMemberNotePrinter.getWarningCount(); if (classMemberNoteCount > 0) { - System.out.println("Note: there were " + classMemberNoteCount + - " references to unknown class members."); - System.out.println(" You should check your configuration for typos."); + out.println("Note: there were " + classMemberNoteCount + + " references to unknown class members."); + out.println(" You should check your configuration for typos."); } int getAnnotationNoteCount = getAnnotationNotePrinter.getWarningCount(); if (getAnnotationNoteCount > 0) { - System.out.println("Note: there were " + getAnnotationNoteCount + - " classes trying to access annotations using reflection."); - System.out.println(" You should consider keeping the annotation attributes"); - System.out.println(" (using '-keepattributes *Annotation*')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); + out.println("Note: there were " + getAnnotationNoteCount + + " classes trying to access annotations using reflection."); + out.println(" You should consider keeping the annotation attributes"); + out.println(" (using '-keepattributes *Annotation*')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); } int getSignatureNoteCount = getSignatureNotePrinter.getWarningCount(); if (getSignatureNoteCount > 0) { - System.out.println("Note: there were " + getSignatureNoteCount + - " classes trying to access generic signatures using reflection."); - System.out.println(" You should consider keeping the signature attributes"); - System.out.println(" (using '-keepattributes Signature')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); + out.println("Note: there were " + getSignatureNoteCount + + " classes trying to access generic signatures using reflection."); + out.println(" You should consider keeping the signature attributes"); + out.println(" (using '-keepattributes Signature')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); } int getEnclosingClassNoteCount = getEnclosingClassNotePrinter.getWarningCount(); if (getEnclosingClassNoteCount > 0) { - System.out.println("Note: there were " + getEnclosingClassNoteCount + - " classes trying to access enclosing classes using reflection."); - System.out.println(" You should consider keeping the inner classes attributes"); - System.out.println(" (using '-keepattributes InnerClasses')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); + out.println("Note: there were " + getEnclosingClassNoteCount + + " classes trying to access enclosing classes using reflection."); + out.println(" You should consider keeping the inner classes attributes"); + out.println(" (using '-keepattributes InnerClasses')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); } int getEnclosingMethodNoteCount = getEnclosingMethodNotePrinter.getWarningCount(); if (getEnclosingMethodNoteCount > 0) { - System.out.println("Note: there were " + getEnclosingMethodNoteCount + - " classes trying to access enclosing methods using reflection."); - System.out.println(" You should consider keeping the enclosing method attributes"); - System.out.println(" (using '-keepattributes InnerClasses,EnclosingMethod')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); + out.println("Note: there were " + getEnclosingMethodNoteCount + + " classes trying to access enclosing methods using reflection."); + out.println(" You should consider keeping the enclosing method attributes"); + out.println(" (using '-keepattributes InnerClasses,EnclosingMethod')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)"); } int descriptorNoteCount = descriptorKeepNotePrinter.getWarningCount(); if (descriptorNoteCount > 0) { - System.out.println("Note: there were " + descriptorNoteCount + - " unkept descriptor classes in kept class members."); - System.out.println(" You should consider explicitly keeping the mentioned classes"); - System.out.println(" (using '-keep')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#descriptorclass)"); + out.println("Note: there were " + descriptorNoteCount + + " unkept descriptor classes in kept class members."); + out.println(" You should consider explicitly keeping the mentioned classes"); + out.println(" (using '-keep')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#descriptorclass)"); } int libraryNoteCount = libraryKeepNotePrinter.getWarningCount(); if (libraryNoteCount > 0) { - System.out.println("Note: there were " + libraryNoteCount + + out.println("Note: there were " + libraryNoteCount + " library classes explicitly being kept."); - System.out.println(" You don't need to keep library classes; they are already left unchanged."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#libraryclass)"); + out.println(" You don't need to keep library classes; they are already left unchanged."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#libraryclass)"); } int dynamicClassReferenceNoteCount = dynamicClassReferenceNotePrinter.getWarningCount(); if (dynamicClassReferenceNoteCount > 0) { - System.out.println("Note: there were " + dynamicClassReferenceNoteCount + - " unresolved dynamic references to classes or interfaces."); - System.out.println(" You should check if you need to specify additional program jars."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass)"); + out.println("Note: there were " + dynamicClassReferenceNoteCount + + " unresolved dynamic references to classes or interfaces."); + out.println(" You should check if you need to specify additional program jars."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass)"); } int classForNameNoteCount = classForNameNotePrinter.getWarningCount(); if (classForNameNoteCount > 0) { - System.out.println("Note: there were " + classForNameNoteCount + - " class casts of dynamically created class instances."); - System.out.println(" You might consider explicitly keeping the mentioned classes and/or"); - System.out.println(" their implementations (using '-keep')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclasscast)"); + out.println("Note: there were " + classForNameNoteCount + + " class casts of dynamically created class instances."); + out.println(" You might consider explicitly keeping the mentioned classes and/or"); + out.println(" their implementations (using '-keep')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclasscast)"); } int getmemberNoteCount = getMemberNotePrinter.getWarningCount(); if (getmemberNoteCount > 0) { - System.out.println("Note: there were " + getmemberNoteCount + - " accesses to class members by means of introspection."); - System.out.println(" You should consider explicitly keeping the mentioned class members"); - System.out.println(" (using '-keep' or '-keepclassmembers')."); - System.out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclassmember)"); + out.println("Note: there were " + getmemberNoteCount + + " accesses to class members by means of reflection."); + out.println(" You should consider explicitly keeping the mentioned class members"); + out.println(" (using '-keep' or '-keepclassmembers')."); + out.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclassmember)"); } // Print out a summary of the warnings, if necessary. int classReferenceWarningCount = classReferenceWarningPrinter.getWarningCount(); if (classReferenceWarningCount > 0) { - System.err.println("Warning: there were " + classReferenceWarningCount + - " unresolved references to classes or interfaces."); - System.err.println(" You may need to add missing library jars or update their versions."); - System.err.println(" If your code works fine without the missing classes, you can suppress"); - System.err.println(" the warnings with '-dontwarn' options."); + err.println("Warning: there were " + classReferenceWarningCount + + " unresolved references to classes or interfaces."); + err.println(" You may need to add missing library jars or update their versions."); + err.println(" If your code works fine without the missing classes, you can suppress"); + err.println(" the warnings with '-dontwarn' options."); if (configuration.skipNonPublicLibraryClasses) { - System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'."); + err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'."); } - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)"); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)"); } int dependencyWarningCount = dependencyWarningPrinter.getWarningCount(); if (dependencyWarningCount > 0) { - System.err.println("Warning: there were " + dependencyWarningCount + - " instances of library classes depending on program classes."); - System.err.println(" You must avoid such dependencies, since the program classes will"); - System.err.println(" be processed, while the library classes will remain unchanged."); - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)"); + err.println("Warning: there were " + dependencyWarningCount + + " instances of library classes depending on program classes."); + err.println(" You must avoid such dependencies, since the program classes will"); + err.println(" be processed, while the library classes will remain unchanged."); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)"); } int programMemberReferenceWarningCount = programMemberReferenceWarningPrinter.getWarningCount(); if (programMemberReferenceWarningCount > 0) { - System.err.println("Warning: there were " + programMemberReferenceWarningCount + - " unresolved references to program class members."); - System.err.println(" Your input classes appear to be inconsistent."); - System.err.println(" You may need to recompile the code."); - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)"); + err.println("Warning: there were " + programMemberReferenceWarningCount + + " unresolved references to program class members."); + err.println(" Your input classes appear to be inconsistent."); + err.println(" You may need to recompile the code."); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)"); } int libraryMemberReferenceWarningCount = libraryMemberReferenceWarningPrinter.getWarningCount(); if (libraryMemberReferenceWarningCount > 0) { - System.err.println("Warning: there were " + libraryMemberReferenceWarningCount + - " unresolved references to library class members."); - System.err.println(" You probably need to update the library versions."); + err.println("Warning: there were " + libraryMemberReferenceWarningCount + + " unresolved references to library class members."); + err.println(" You probably need to update the library versions."); if (!configuration.skipNonPublicLibraryClassMembers) { - System.err.println(" Alternatively, you may have to specify the option "); - System.err.println(" '-dontskipnonpubliclibraryclassmembers'."); + err.println(" Alternatively, you may have to specify the option "); + err.println(" '-dontskipnonpubliclibraryclassmembers'."); } if (configuration.skipNonPublicLibraryClasses) { - System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'."); + err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'."); } - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)"); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)"); } if ((classReferenceWarningCount > 0 || @@ -491,15 +491,15 @@ configuration.warn.isEmpty() || configuration.ignoreWarnings)) { - System.out.println("Note: you're ignoring all warnings!"); + out.println("Note: you're ignoring all warnings!"); } // Discard unused library classes. if (configuration.verbose) { - System.out.println("Ignoring unused library classes..."); - System.out.println(" Original number of library classes: " + originalLibraryClassPoolSize); - System.out.println(" Final number of library classes: " + libraryClassPool.size()); + out.println("Ignoring unused library classes..."); + out.println(" Original number of library classes: " + originalLibraryClassPoolSize); + out.println(" Final number of library classes: " + libraryClassPool.size()); } } diff -Nru proguard-6.0.3/core/src/proguard/InputReader.java proguard-6.2.0/core/src/proguard/InputReader.java --- proguard-6.0.3/core/src/proguard/InputReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/InputReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -25,7 +25,7 @@ import proguard.classfile.visitor.*; import proguard.io.*; -import java.io.IOException; +import java.io.*; /** * This class reads the input class files. @@ -60,8 +60,13 @@ public void execute(ClassPool programClassPool, ClassPool libraryClassPool) throws IOException { - WarningPrinter warningPrinter = new WarningPrinter(System.err, configuration.warn); - WarningPrinter notePrinter = new WarningPrinter(System.out, configuration.note); + // We're using the system's default character encoding for writing to + // the standard output and error output. + PrintWriter out = new PrintWriter(System.out, true); + PrintWriter err = new PrintWriter(System.err, true); + + WarningPrinter notePrinter = new WarningPrinter(out, configuration.note); + WarningPrinter warningPrinter = new WarningPrinter(err, configuration.warn); DuplicateClassPrinter duplicateClassPrinter = new DuplicateClassPrinter(notePrinter); @@ -127,25 +132,25 @@ int noteCount = notePrinter.getWarningCount(); if (noteCount > 0) { - System.err.println("Note: there were " + noteCount + - " duplicate class definitions."); - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass)"); + err.println("Note: there were " + noteCount + + " duplicate class definitions."); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass)"); } // Print out a summary of the warnings, if necessary. int warningCount = warningPrinter.getWarningCount(); if (warningCount > 0) { - System.err.println("Warning: there were " + warningCount + - " classes in incorrectly named files."); - System.err.println(" You should make sure all file names correspond to their class names."); - System.err.println(" The directory hierarchies must correspond to the package hierarchies."); - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unexpectedclass)"); + err.println("Warning: there were " + warningCount + + " classes in incorrectly named files."); + err.println(" You should make sure all file names correspond to their class names."); + err.println(" The directory hierarchies must correspond to the package hierarchies."); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#unexpectedclass)"); if (!configuration.ignoreWarnings) { - System.err.println(" If you don't mind the mentioned classes not being written out,"); - System.err.println(" you could try your luck using the '-ignorewarnings' option."); + err.println(" If you don't mind the mentioned classes not being written out,"); + err.println(" you could try your luck using the '-ignorewarnings' option."); throw new IOException("Please correct the above warnings first."); } } diff -Nru proguard-6.0.3/core/src/proguard/io/CascadingDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/CascadingDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/CascadingDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/CascadingDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ClassDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/ClassDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/ClassDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ClassDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ClassFilter.java proguard-6.2.0/core/src/proguard/io/ClassFilter.java --- proguard-6.0.3/core/src/proguard/io/ClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ClassMapDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/ClassMapDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/ClassMapDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ClassMapDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ClassPathDataEntry.java proguard-6.2.0/core/src/proguard/io/ClassPathDataEntry.java --- proguard-6.0.3/core/src/proguard/io/ClassPathDataEntry.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ClassPathDataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ClassReader.java proguard-6.2.0/core/src/proguard/io/ClassReader.java --- proguard-6.0.3/core/src/proguard/io/ClassReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ClassReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryClassWriter.java proguard-6.2.0/core/src/proguard/io/DataEntryClassWriter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryClassWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryClassWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryCopier.java proguard-6.2.0/core/src/proguard/io/DataEntryCopier.java --- proguard-6.0.3/core/src/proguard/io/DataEntryCopier.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryCopier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryDirectoryFilter.java proguard-6.2.0/core/src/proguard/io/DataEntryDirectoryFilter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryDirectoryFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryDirectoryFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryFilter.java proguard-6.2.0/core/src/proguard/io/DataEntryFilter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntry.java proguard-6.2.0/core/src/proguard/io/DataEntry.java --- proguard-6.0.3/core/src/proguard/io/DataEntry.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryNameFilter.java proguard-6.2.0/core/src/proguard/io/DataEntryNameFilter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryNameFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryNameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryParentFilter.java proguard-6.2.0/core/src/proguard/io/DataEntryParentFilter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryParentFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryParentFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryPump.java proguard-6.2.0/core/src/proguard/io/DataEntryPump.java --- proguard-6.0.3/core/src/proguard/io/DataEntryPump.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryPump.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryReader.java proguard-6.2.0/core/src/proguard/io/DataEntryReader.java --- proguard-6.0.3/core/src/proguard/io/DataEntryReader.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryRewriter.java proguard-6.2.0/core/src/proguard/io/DataEntryRewriter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryRewriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryRewriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DataEntryWriter.java proguard-6.2.0/core/src/proguard/io/DataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/DataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DirectoryFilter.java proguard-6.2.0/core/src/proguard/io/DirectoryFilter.java --- proguard-6.0.3/core/src/proguard/io/DirectoryFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DirectoryFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DirectoryPump.java proguard-6.2.0/core/src/proguard/io/DirectoryPump.java --- proguard-6.0.3/core/src/proguard/io/DirectoryPump.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DirectoryPump.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/DirectoryWriter.java proguard-6.2.0/core/src/proguard/io/DirectoryWriter.java --- proguard-6.0.3/core/src/proguard/io/DirectoryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/DirectoryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ExtraDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/ExtraDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/ExtraDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ExtraDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/FileDataEntry.java proguard-6.2.0/core/src/proguard/io/FileDataEntry.java --- proguard-6.0.3/core/src/proguard/io/FileDataEntry.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/FileDataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/FilteredDataEntryReader.java proguard-6.2.0/core/src/proguard/io/FilteredDataEntryReader.java --- proguard-6.0.3/core/src/proguard/io/FilteredDataEntryReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/FilteredDataEntryReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/FilteredDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/FilteredDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/FilteredDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/FilteredDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/Finisher.java proguard-6.2.0/core/src/proguard/io/Finisher.java --- proguard-6.0.3/core/src/proguard/io/Finisher.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/Finisher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/IdleRewriter.java proguard-6.2.0/core/src/proguard/io/IdleRewriter.java --- proguard-6.0.3/core/src/proguard/io/IdleRewriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/IdleRewriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/JarReader.java proguard-6.2.0/core/src/proguard/io/JarReader.java --- proguard-6.0.3/core/src/proguard/io/JarReader.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/JarReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -21,11 +21,12 @@ package proguard.io; import java.io.IOException; +import java.nio.charset.Charset; import java.util.zip.*; /** * This DataEntryReader lets a given DataEntryReader read all data entries of - * the read jar/war/zip data entries. + * the read archive data entries. * * @author Eric Lafortune */ @@ -65,7 +66,7 @@ dataEntry.getInputStream().read(new byte[4]); } - ZipInputStream zipInputStream = new ZipInputStream(dataEntry.getInputStream()); + ZipInputStream zipInputStream = new ZipInputStream(dataEntry.getInputStream(), Charset.forName("UTF-8")); try { diff -Nru proguard-6.0.3/core/src/proguard/io/JarWriter.java proguard-6.2.0/core/src/proguard/io/JarWriter.java --- proguard-6.0.3/core/src/proguard/io/JarWriter.java 2018-04-08 21:12:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/JarWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ManifestRewriter.java proguard-6.2.0/core/src/proguard/io/ManifestRewriter.java --- proguard-6.0.3/core/src/proguard/io/ManifestRewriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ManifestRewriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/NameFilteredDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/NameFilteredDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/NameFilteredDataEntryWriter.java 2018-02-01 21:58:51.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/NameFilteredDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/NameFilter.java proguard-6.2.0/core/src/proguard/io/NameFilter.java --- proguard-6.0.3/core/src/proguard/io/NameFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/NameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ParentDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/ParentDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/ParentDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ParentDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/PrefixAddingDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/PrefixAddingDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/PrefixAddingDataEntryWriter.java 2018-04-08 22:02:30.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/PrefixAddingDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/PrefixStrippingDataEntryReader.java proguard-6.2.0/core/src/proguard/io/PrefixStrippingDataEntryReader.java --- proguard-6.0.3/core/src/proguard/io/PrefixStrippingDataEntryReader.java 2018-04-08 21:57:40.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/PrefixStrippingDataEntryReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/RenamedDataEntry.java proguard-6.2.0/core/src/proguard/io/RenamedDataEntry.java --- proguard-6.0.3/core/src/proguard/io/RenamedDataEntry.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/RenamedDataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/RenamedDataEntryReader.java proguard-6.2.0/core/src/proguard/io/RenamedDataEntryReader.java --- proguard-6.0.3/core/src/proguard/io/RenamedDataEntryReader.java 2018-02-01 22:07:13.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/RenamedDataEntryReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/RenamedDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/RenamedDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/RenamedDataEntryWriter.java 2018-02-01 22:06:45.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/RenamedDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/RenamedParentDataEntryWriter.java proguard-6.2.0/core/src/proguard/io/RenamedParentDataEntryWriter.java --- proguard-6.0.3/core/src/proguard/io/RenamedParentDataEntryWriter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/RenamedParentDataEntryWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/WrappedDataEntry.java proguard-6.2.0/core/src/proguard/io/WrappedDataEntry.java --- proguard-6.0.3/core/src/proguard/io/WrappedDataEntry.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/WrappedDataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ZipDataEntry.java proguard-6.2.0/core/src/proguard/io/ZipDataEntry.java --- proguard-6.0.3/core/src/proguard/io/ZipDataEntry.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ZipDataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ZipFileDataEntry.java proguard-6.2.0/core/src/proguard/io/ZipFileDataEntry.java --- proguard-6.0.3/core/src/proguard/io/ZipFileDataEntry.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ZipFileDataEntry.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/io/ZipOutput.java proguard-6.2.0/core/src/proguard/io/ZipOutput.java --- proguard-6.0.3/core/src/proguard/io/ZipOutput.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/io/ZipOutput.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/KeepClassMemberChecker.java proguard-6.2.0/core/src/proguard/KeepClassMemberChecker.java --- proguard-6.0.3/core/src/proguard/KeepClassMemberChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/KeepClassMemberChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/KeepClassSpecification.java proguard-6.2.0/core/src/proguard/KeepClassSpecification.java --- proguard-6.0.3/core/src/proguard/KeepClassSpecification.java 2018-02-24 21:45:08.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/KeepClassSpecification.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/KeepClassSpecificationVisitorFactory.java proguard-6.2.0/core/src/proguard/KeepClassSpecificationVisitorFactory.java --- proguard-6.0.3/core/src/proguard/KeepClassSpecificationVisitorFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/KeepClassSpecificationVisitorFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -173,10 +173,14 @@ classVisitor = null; } - // Don't visit the code attributes if not specified. - attributeVisitor = keepClassSpecification.markCodeAttributes ? - new AttributeNameFilter(ClassConstants.ATTR_Code, attributeVisitor) : - null; + // Do we have an attribute visitor? + if (attributeVisitor != null) + { + // Don't visit the code attributes if not specified. + attributeVisitor = keepClassSpecification.markCodeAttributes ? + new AttributeNameFilter(ClassConstants.ATTR_Code, attributeVisitor) : + null; + } ClassSpecification condition = keepClassSpecification.condition; if (condition != null) diff -Nru proguard-6.0.3/core/src/proguard/LibraryKeepChecker.java proguard-6.2.0/core/src/proguard/LibraryKeepChecker.java --- proguard-6.0.3/core/src/proguard/LibraryKeepChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/LibraryKeepChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/LineWordReader.java proguard-6.2.0/core/src/proguard/LineWordReader.java --- proguard-6.0.3/core/src/proguard/LineWordReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/LineWordReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -21,6 +21,7 @@ package proguard; import java.io.*; +import java.net.URL; /** @@ -45,6 +46,20 @@ this.reader = lineNumberReader; this.description = description; + } + + + /** + * Creates a new LineWordReader for the given input. + */ + public LineWordReader(LineNumberReader lineNumberReader, + String description, + URL baseURL) throws IOException + { + super(baseURL); + + this.reader = lineNumberReader; + this.description = description; } diff -Nru proguard-6.0.3/core/src/proguard/MemberSpecification.java proguard-6.2.0/core/src/proguard/MemberSpecification.java --- proguard-6.0.3/core/src/proguard/MemberSpecification.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/MemberSpecification.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -20,7 +20,6 @@ */ package proguard; - import java.util.List; /** diff -Nru proguard-6.0.3/core/src/proguard/MemberValueSpecification.java proguard-6.2.0/core/src/proguard/MemberValueSpecification.java --- proguard-6.0.3/core/src/proguard/MemberValueSpecification.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/MemberValueSpecification.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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; + +import proguard.util.ArrayUtil; + +/** + * This member specification assigns a constant value or value range to the + * class members. + * + * @author Eric Lafortune + */ +public class MemberValueSpecification extends MemberSpecification +{ + public Number[] values; + + + /** + * Creates a new option to keep all possible class members. + */ + public MemberValueSpecification() + { + this(0, + 0, + null, + null, + null, + null); + } + + + /** + * Creates a new option to keep the specified class member(s). + * + * @param requiredSetAccessFlags the class access flags that must be set + * in order for the class to apply. + * @param requiredUnsetAccessFlags the class access flags that must be unset + * in order for the class to apply. + * @param annotationType the name of the class that must be an + * annotation in order for the class member + * to apply. The name may be null to specify + * that no annotation is required. + * @param name the class member name. The name may be + * null to specify any class member or it + * may contain "*" or "?" wildcards. + * @param descriptor the class member descriptor. The + * descriptor may be null to specify any + * class member or it may contain + * "**", "*", or "?" wildcards. + * @param values the constant value or value range + * assigned to this class member. + */ + public MemberValueSpecification(int requiredSetAccessFlags, + int requiredUnsetAccessFlags, + String annotationType, + String name, + String descriptor, + Number[] values) + { + super(requiredSetAccessFlags, + requiredUnsetAccessFlags, + annotationType, + name, + descriptor); + + this.values = values; + } + + + + // Implementations for Object. + + public boolean equals(Object object) + { + if (object == null) + { + return false; + } + + MemberValueSpecification other = (MemberValueSpecification)object; + return + super.equals(other) && + ArrayUtil.equalOrNull(values, other.values); + } + + public int hashCode() + { + return + super.hashCode() ^ + ArrayUtil.hashCodeOrNull(values); + } +} diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/AttributeShrinker.java proguard-6.2.0/core/src/proguard/obfuscate/AttributeShrinker.java --- proguard-6.0.3/core/src/proguard/obfuscate/AttributeShrinker.java 2018-05-06 20:26:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/AttributeShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/AttributeUsageMarker.java proguard-6.2.0/core/src/proguard/obfuscate/AttributeUsageMarker.java --- proguard-6.0.3/core/src/proguard/obfuscate/AttributeUsageMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/AttributeUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/ClassObfuscator.java proguard-6.2.0/core/src/proguard/obfuscate/ClassObfuscator.java --- proguard-6.0.3/core/src/proguard/obfuscate/ClassObfuscator.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/ClassObfuscator.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/ClassRenamer.java proguard-6.2.0/core/src/proguard/obfuscate/ClassRenamer.java --- proguard-6.0.3/core/src/proguard/obfuscate/ClassRenamer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/ClassRenamer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/DictionaryNameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/DictionaryNameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/DictionaryNameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/DictionaryNameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MapCleaner.java proguard-6.2.0/core/src/proguard/obfuscate/MapCleaner.java --- proguard-6.0.3/core/src/proguard/obfuscate/MapCleaner.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MapCleaner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MappingKeeper.java proguard-6.2.0/core/src/proguard/obfuscate/MappingKeeper.java --- proguard-6.0.3/core/src/proguard/obfuscate/MappingKeeper.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MappingKeeper.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MappingPrinter.java proguard-6.2.0/core/src/proguard/obfuscate/MappingPrinter.java --- proguard-6.0.3/core/src/proguard/obfuscate/MappingPrinter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MappingPrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -27,7 +27,7 @@ import proguard.classfile.visitor.*; import proguard.optimize.peephole.LineNumberLinearizer; -import java.io.PrintStream; +import java.io.*; import java.util.Stack; @@ -45,28 +45,19 @@ MemberVisitor, AttributeVisitor { - private final PrintStream ps; + private final PrintWriter pw; // A field serving as a return value for the visitor methods. private boolean printed; /** - * Creates a new MappingPrinter that prints to System.out. + * Creates a new MappingPrinter that prints to the given writer. + * @param printWriter the writer to which to print. */ - public MappingPrinter() + public MappingPrinter(PrintWriter printWriter) { - this(System.out); - } - - - /** - * Creates a new MappingPrinter that prints to the given stream. - * @param printStream the stream to which to print - */ - public MappingPrinter(PrintStream printStream) - { - this.ps = printStream; + this.pw = printWriter; } @@ -78,7 +69,7 @@ String newName = ClassObfuscator.newClassName(programClass); // Print out the class mapping. - ps.println(ClassUtil.externalClassName(name) + + pw.println(ClassUtil.externalClassName(name) + " -> " + ClassUtil.externalClassName(newName) + ":"); @@ -101,7 +92,7 @@ } // Print out the field mapping. - ps.println(" " + + pw.println(" " + ClassUtil.externalType(programField.getDescriptor(programClass)) + " " + fieldName + " -> " + @@ -125,7 +116,7 @@ // Otherwise print out the method mapping without line numbers. if (!printed) { - ps.println(" " + + pw.println(" " + ClassUtil.externalMethodReturnType(programMethod.getDescriptor(programClass)) + " " + methodName + JavaConstants.METHOD_ARGUMENTS_OPEN + ClassUtil.externalMethodArguments(programMethod.getDescriptor(programClass)) + JavaConstants.METHOD_ARGUMENTS_CLOSE + @@ -169,7 +160,7 @@ { // Print out the line number range of the method, // ignoring line numbers of any inlined methods. - ps.println(" " + + pw.println(" " + lowestLineNumber + ":" + highestLineNumber + ":" + ClassUtil.externalMethodReturnType(method.getDescriptor(clazz)) + " " + @@ -181,7 +172,7 @@ else { // Print out the method mapping without line numbers. - ps.println(" " + + pw.println(" " + ClassUtil.externalMethodReturnType(method.getDescriptor(clazz)) + " " + methodName + JavaConstants.METHOD_ARGUMENTS_OPEN + ClassUtil.externalMethodArguments(method.getDescriptor(clazz)) + JavaConstants.METHOD_ARGUMENTS_CLOSE + @@ -204,7 +195,8 @@ // We're testing on the identities out of convenience. String previousSource = previousInfo.getSource(); String source = info.getSource(); - if (source != previousSource) + // Source can be null for injected code. + if (source != null && source != previousSource) { // Are we entering or exiting the block? int previousLineNumber = previousInfo.u2lineNumber; @@ -234,6 +226,12 @@ enclosingLineNumbers.pop(); } } + else if (source == null && previousSource != null) + { + // When exiting a top-level inlined block, the source might be null. + // See LineNumberLinearizer, line 185, exiting an inlined block. + enclosingLineNumbers.pop(); + } previousInfo = info; } @@ -277,7 +275,7 @@ int shiftedEndLineNumber = shiftedStartLineNumber + endLineNumber - startLineNumber; // Print out the line number range of the inlined method. - ps.println(" " + + pw.println(" " + shiftedStartLineNumber + ":" + shiftedEndLineNumber + ":" + ClassUtil.externalMethodReturnType(inlinedMethodDescriptor) + " " + @@ -302,8 +300,6 @@ shiftedEndLineNumber, enclosingInfo, obfuscatedMethodName); - - } } @@ -352,7 +348,7 @@ } // Print out the line number of the enclosing method. - ps.println(" " + + pw.println(" " + shiftedRange + ":" + ClassUtil.externalMethodReturnType(enclosingMethodDescriptor) + " " + (enclosingClassName.equals(className) ? "" : diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MappingProcessor.java proguard-6.2.0/core/src/proguard/obfuscate/MappingProcessor.java --- proguard-6.0.3/core/src/proguard/obfuscate/MappingProcessor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MappingProcessor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MappingReader.java proguard-6.2.0/core/src/proguard/obfuscate/MappingReader.java --- proguard-6.0.3/core/src/proguard/obfuscate/MappingReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MappingReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -46,9 +46,11 @@ */ public void pump(MappingProcessor mappingProcessor) throws IOException { - LineNumberReader reader = new LineNumberReader( - new BufferedReader( - new FileReader(mappingFile))); + LineNumberReader reader = + new LineNumberReader( + new BufferedReader( + new InputStreamReader( + new FileInputStream(mappingFile), "UTF-8"))); try { String className = null; diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MemberNameCleaner.java proguard-6.2.0/core/src/proguard/obfuscate/MemberNameCleaner.java --- proguard-6.0.3/core/src/proguard/obfuscate/MemberNameCleaner.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MemberNameCleaner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MemberNameCollector.java proguard-6.2.0/core/src/proguard/obfuscate/MemberNameCollector.java --- proguard-6.0.3/core/src/proguard/obfuscate/MemberNameCollector.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MemberNameCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MemberNameConflictFixer.java proguard-6.2.0/core/src/proguard/obfuscate/MemberNameConflictFixer.java --- proguard-6.0.3/core/src/proguard/obfuscate/MemberNameConflictFixer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MemberNameConflictFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MemberNameFilter.java proguard-6.2.0/core/src/proguard/obfuscate/MemberNameFilter.java --- proguard-6.0.3/core/src/proguard/obfuscate/MemberNameFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MemberNameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MemberObfuscator.java proguard-6.2.0/core/src/proguard/obfuscate/MemberObfuscator.java --- proguard-6.0.3/core/src/proguard/obfuscate/MemberObfuscator.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MemberObfuscator.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MemberSpecialNameFilter.java proguard-6.2.0/core/src/proguard/obfuscate/MemberSpecialNameFilter.java --- proguard-6.0.3/core/src/proguard/obfuscate/MemberSpecialNameFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MemberSpecialNameFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/MultiMappingProcessor.java proguard-6.2.0/core/src/proguard/obfuscate/MultiMappingProcessor.java --- proguard-6.0.3/core/src/proguard/obfuscate/MultiMappingProcessor.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/MultiMappingProcessor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/NameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/NameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/NameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/NameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/NameFactoryResetter.java proguard-6.2.0/core/src/proguard/obfuscate/NameFactoryResetter.java --- proguard-6.0.3/core/src/proguard/obfuscate/NameFactoryResetter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/NameFactoryResetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/NameMarker.java proguard-6.2.0/core/src/proguard/obfuscate/NameMarker.java --- proguard-6.0.3/core/src/proguard/obfuscate/NameMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/NameMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/NumericNameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/NumericNameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/NumericNameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/NumericNameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/Obfuscator.java proguard-6.2.0/core/src/proguard/obfuscate/Obfuscator.java --- proguard-6.0.3/core/src/proguard/obfuscate/Obfuscator.java 2018-04-12 10:46:17.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/Obfuscator.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -66,21 +66,30 @@ throw new IOException("You have to specify '-keep' options for the obfuscation step."); } + // We're using the system's default character encoding for writing to + // the standard output and error output. + PrintWriter out = new PrintWriter(System.out, true); + PrintWriter err = new PrintWriter(System.err, true); + // Clean up any old visitor info. programClassPool.classesAccept(new ClassCleaner()); libraryClassPool.classesAccept(new ClassCleaner()); - // If the class member names have to correspond globally, - // link all class members in all classes, otherwise - // link all non-private methods in all class hierarchies. + // Link all non-private, non-static methods in all class hierarchies. ClassVisitor memberInfoLinker = - configuration.useUniqueClassMemberNames ? - (ClassVisitor)new AllMemberVisitor(new MethodLinker()) : - (ClassVisitor)new BottomClassFilter(new MethodLinker()); + new BottomClassFilter(new MethodLinker()); programClassPool.classesAccept(memberInfoLinker); libraryClassPool.classesAccept(memberInfoLinker); + // If the class member names have to correspond globally, + // additionally link all class members in all program classes. + if (configuration.useUniqueClassMemberNames) + { + programClassPool.classesAccept(new AllMemberVisitor( + new MethodLinker())); + } + // Create a visitor for marking the seeds. NameMarker nameMarker = new NameMarker(); ClassPoolVisitor classPoolvisitor = @@ -165,7 +174,14 @@ // override the names of library classes and of library class members. if (configuration.applyMapping != null) { - WarningPrinter warningPrinter = new WarningPrinter(System.err, configuration.warn); + if (configuration.verbose) + { + out.println("Applying mapping from [" + + PrintWriterUtil.fileName(configuration.applyMapping) + + "]..."); + } + + WarningPrinter warningPrinter = new WarningPrinter(err, configuration.warn); MappingReader reader = new MappingReader(configuration.applyMapping); @@ -182,17 +198,17 @@ int warningCount = warningPrinter.getWarningCount(); if (warningCount > 0) { - System.err.println("Warning: there were " + warningCount + - " kept classes and class members that were remapped anyway."); - System.err.println(" You should adapt your configuration or edit the mapping file."); + err.println("Warning: there were " + warningCount + + " kept classes and class members that were remapped anyway."); + err.println(" You should adapt your configuration or edit the mapping file."); if (!configuration.ignoreWarnings) { - System.err.println(" If you are sure this remapping won't hurt, you could try your luck"); - System.err.println(" using the '-ignorewarnings' option."); + err.println(" If you are sure this remapping won't hurt,"); + err.println(" you could try your luck using the '-ignorewarnings' option."); } - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#mappingconflict1)"); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#mappingconflict1)"); if (!configuration.ignoreWarnings) { @@ -230,7 +246,7 @@ nameFactory); } - WarningPrinter warningPrinter = new WarningPrinter(System.err, configuration.warn); + WarningPrinter warningPrinter = new WarningPrinter(err, configuration.warn); // Maintain a map of names to avoid [descriptor - new name - old name]. Map descriptorMap = new HashMap(); @@ -426,17 +442,17 @@ int warningCount = warningPrinter.getWarningCount(); if (warningCount > 0) { - System.err.println("Warning: there were " + warningCount + + err.println("Warning: there were " + warningCount + " conflicting class member name mappings."); - System.err.println(" Your configuration may be inconsistent."); + err.println(" Your configuration may be inconsistent."); if (!configuration.ignoreWarnings) { - System.err.println(" If you are sure the conflicts are harmless,"); - System.err.println(" you could try your luck using the '-ignorewarnings' option."); + err.println(" If you are sure the conflicts are harmless,"); + err.println(" you could try your luck using the '-ignorewarnings' option."); } - System.err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#mappingconflict2)"); + err.println(" (http://proguard.sourceforge.net/manual/troubleshooting.html#mappingconflict2)"); if (!configuration.ignoreWarnings) { @@ -447,22 +463,26 @@ // Print out the mapping, if requested. if (configuration.printMapping != null) { - PrintStream ps = - configuration.printMapping == Configuration.STD_OUT ? System.out : - new PrintStream( - new BufferedOutputStream( - new FileOutputStream(configuration.printMapping))); + if (configuration.verbose) + { + out.println("Printing mapping to [" + + PrintWriterUtil.fileName(configuration.printMapping) + + "]..."); + } - // Print out items that will be removed. - programClassPool.classesAcceptAlphabetically(new MappingPrinter(ps)); + PrintWriter mappingWriter = + PrintWriterUtil.createPrintWriter(configuration.printMapping, out); - if (ps == System.out) + try { - ps.flush(); + // Print out items that will be renamed. + programClassPool.classesAcceptAlphabetically( + new MappingPrinter(mappingWriter)); } - else + finally { - ps.close(); + PrintWriterUtil.closePrintWriter(configuration.printMapping, + mappingWriter); } } @@ -478,7 +498,7 @@ // Update all references to these new names. programClassPool.classesAccept(new ClassReferenceFixer(false)); libraryClassPool.classesAccept(new ClassReferenceFixer(false)); - programClassPool.classesAccept(new MemberReferenceFixer()); + programClassPool.classesAccept(new MemberReferenceFixer(configuration.android)); // Make package visible elements public or protected, if obfuscated // classes are being repackaged aggressively. diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/ParameterNameMarker.java proguard-6.2.0/core/src/proguard/obfuscate/ParameterNameMarker.java --- proguard-6.0.3/core/src/proguard/obfuscate/ParameterNameMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/ParameterNameMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/PrefixingNameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/PrefixingNameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/PrefixingNameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/PrefixingNameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/RenamedFlagSetter.java proguard-6.2.0/core/src/proguard/obfuscate/RenamedFlagSetter.java --- proguard-6.0.3/core/src/proguard/obfuscate/RenamedFlagSetter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/RenamedFlagSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/SimpleNameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/SimpleNameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/SimpleNameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/SimpleNameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/SourceFileRenamer.java proguard-6.2.0/core/src/proguard/obfuscate/SourceFileRenamer.java --- proguard-6.0.3/core/src/proguard/obfuscate/SourceFileRenamer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/SourceFileRenamer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/SpecialNameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/SpecialNameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/SpecialNameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/SpecialNameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/obfuscate/UniqueMemberNameFactory.java proguard-6.2.0/core/src/proguard/obfuscate/UniqueMemberNameFactory.java --- proguard-6.0.3/core/src/proguard/obfuscate/UniqueMemberNameFactory.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/obfuscate/UniqueMemberNameFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/BootstrapMethodArgumentShrinker.java proguard-6.2.0/core/src/proguard/optimize/BootstrapMethodArgumentShrinker.java --- proguard-6.0.3/core/src/proguard/optimize/BootstrapMethodArgumentShrinker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/BootstrapMethodArgumentShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/ChangedCodePrinter.java proguard-6.2.0/core/src/proguard/optimize/ChangedCodePrinter.java --- proguard-6.0.3/core/src/proguard/optimize/ChangedCodePrinter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/ChangedCodePrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -84,6 +84,18 @@ } + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + attributeVisitor.visitNestHostAttribute(clazz, nestHostAttribute); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + attributeVisitor.visitNestMembersAttribute(clazz, nestMembersAttribute); + } + + public void visitModuleAttribute(Clazz clazz, ModuleAttribute moduleAttribute) { attributeVisitor.visitModuleAttribute(clazz, moduleAttribute); diff -Nru proguard-6.0.3/core/src/proguard/optimize/ConstantMemberFilter.java proguard-6.2.0/core/src/proguard/optimize/ConstantMemberFilter.java --- proguard-6.0.3/core/src/proguard/optimize/ConstantMemberFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/ConstantMemberFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/ConstantParameterFilter.java proguard-6.2.0/core/src/proguard/optimize/ConstantParameterFilter.java --- proguard-6.0.3/core/src/proguard/optimize/ConstantParameterFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/ConstantParameterFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -58,14 +58,15 @@ { // All parameters of non-static methods are shifted by one in the local // variable frame. - int firstParameterIndex = - (programMethod.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; + boolean isStatic = + (programMethod.getAccessFlags() & ClassConstants.ACC_STATIC) != 0; + int parameterStart = isStatic ? 0 : 1; int parameterCount = - ClassUtil.internalMethodParameterCount(programMethod.getDescriptor(programClass)); + ClassUtil.internalMethodParameterCount(programMethod.getDescriptor(programClass), + isStatic); - for (int index = firstParameterIndex; index < parameterCount; index++) + for (int index = parameterStart; index < parameterCount; index++) { Value value = StoringInvocationUnit.getMethodParameterValue(programMethod, index); if (value != null && diff -Nru proguard-6.0.3/core/src/proguard/optimize/DuplicateInitializerFixer.java proguard-6.2.0/core/src/proguard/optimize/DuplicateInitializerFixer.java --- proguard-6.0.3/core/src/proguard/optimize/DuplicateInitializerFixer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/DuplicateInitializerFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/DuplicateInitializerInvocationFixer.java proguard-6.2.0/core/src/proguard/optimize/DuplicateInitializerInvocationFixer.java --- proguard-6.0.3/core/src/proguard/optimize/DuplicateInitializerInvocationFixer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/DuplicateInitializerInvocationFixer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/EvaluationShrinker.java proguard-6.2.0/core/src/proguard/optimize/evaluation/EvaluationShrinker.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/EvaluationShrinker.java 2018-02-01 17:43:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/EvaluationShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -53,38 +53,48 @@ private static boolean DEBUG_RESULTS = DEBUG; //*/ - private static final int UNSUPPORTED = -1; - private static final int NOP = InstructionConstants.OP_NOP & 0xff; - private static final int POP = InstructionConstants.OP_POP & 0xff; - private static final int POP2 = InstructionConstants.OP_POP2 & 0xff; - private static final int DUP = InstructionConstants.OP_DUP & 0xff; - private static final int DUP_X1 = InstructionConstants.OP_DUP_X1 & 0xff; - private static final int DUP_X2 = InstructionConstants.OP_DUP_X2 & 0xff; - private static final int DUP2 = InstructionConstants.OP_DUP2 & 0xff; - private static final int DUP2_X1 = InstructionConstants.OP_DUP2_X1 & 0xff; - private static final int DUP2_X2 = InstructionConstants.OP_DUP2_X2 & 0xff; - private static final int SWAP = InstructionConstants.OP_SWAP & 0xff; - private static final int MOV_X2 = DUP_X2 | (POP << 8); - private static final int MOV2_X1 = DUP2_X1 | (POP2 << 8); - private static final int MOV2_X2 = DUP2_X2 | (POP2 << 8); - private static final int POP_X1 = SWAP | (POP << 8); - private static final int POP_X2 = DUP2_X1 | (POP2 << 8) | (POP << 16); - private static final int POP_X3 = UNSUPPORTED; - private static final int POP2_X1 = DUP_X2 | (POP << 8) | (POP2 << 16); - private static final int POP2_X2 = DUP2_X2 | (POP2 << 8) | (POP2 << 16); - private static final int POP3 = POP2 | (POP << 8); - private static final int POP4 = POP2 | (POP2 << 8); - private static final int POP_DUP = POP | (DUP << 8); - private static final int POP_SWAP_POP = POP | (SWAP << 8) | (POP << 16); - private static final int POP2_SWAP_POP = POP2 | (SWAP << 8) | (POP << 16); - private static final int SWAP_DUP_X1 = SWAP | (DUP_X1 << 8); - private static final int SWAP_DUP_X1_SWAP = SWAP | (DUP_X1 << 8) | (SWAP << 16); - private static final int SWAP_POP_DUP = SWAP | (POP << 8) | (DUP << 16); - private static final int SWAP_POP_DUP_X1 = SWAP | (POP << 8) | (DUP_X1 << 16); - private static final int DUP_X2_POP2 = DUP_X2 | (POP2 << 8); - private static final int DUP2_X1_POP3 = DUP2_X1 | (POP2 << 8) | (POP << 16); - private static final int DUP2_X2_POP3 = DUP2_X2 | (POP2 << 8) | (POP << 16); - private static final int DUP2_X2_SWAP_POP = DUP2_X2 | (SWAP << 8) | (POP << 16); + private static final int UNSUPPORTED = -1; + private static final int NOP = InstructionConstants.OP_NOP & 0xff; + private static final int POP = InstructionConstants.OP_POP & 0xff; + private static final int POP2 = InstructionConstants.OP_POP2 & 0xff; + private static final int DUP = InstructionConstants.OP_DUP & 0xff; + private static final int DUP_X1 = InstructionConstants.OP_DUP_X1 & 0xff; + private static final int DUP_X2 = InstructionConstants.OP_DUP_X2 & 0xff; + private static final int DUP2 = InstructionConstants.OP_DUP2 & 0xff; + private static final int DUP2_X1 = InstructionConstants.OP_DUP2_X1 & 0xff; + private static final int DUP2_X2 = InstructionConstants.OP_DUP2_X2 & 0xff; + private static final int SWAP = InstructionConstants.OP_SWAP & 0xff; + private static final int MOV_X2 = DUP_X2 | (POP << 8); + private static final int MOV2_X1 = DUP2_X1 | (POP2 << 8); + private static final int MOV2_X2 = DUP2_X2 | (POP2 << 8); + private static final int POP_X1 = SWAP | (POP << 8); + private static final int POP_X2 = DUP2_X1 | (POP2 << 8) | (POP << 16); + private static final int POP_X3 = UNSUPPORTED; + private static final int POP2_X1 = DUP_X2 | (POP << 8) | (POP2 << 16); + private static final int POP2_X2 = DUP2_X2 | (POP2 << 8) | (POP2 << 16); + private static final int POP3 = POP2 | (POP << 8); + private static final int POP4 = POP2 | (POP2 << 8); + private static final int POP_DUP = POP | (DUP << 8); + private static final int POP_DUP_X1 = POP | (DUP_X1 << 8); + private static final int POP_SWAP = POP | (SWAP << 8); + private static final int POP_SWAP_POP = POP | (SWAP << 8) | (POP << 16); + private static final int POP_SWAP_POP_DUP = POP | (SWAP << 8) | (POP << 16) | (DUP << 24); + private static final int POP2_SWAP_POP = POP2 | (SWAP << 8) | (POP << 16); + private static final int SWAP_DUP_X1 = SWAP | (DUP_X1 << 8); + private static final int SWAP_DUP_X1_POP3 = SWAP | (DUP_X1 << 8) | (POP2 << 16) | (POP << 24); + private static final int SWAP_DUP2_X1_POP3 = SWAP | (DUP2_X1 << 8) | (POP2 << 16) | (POP << 24); + private static final int SWAP_DUP_X1_SWAP = SWAP | (DUP_X1 << 8) | (SWAP << 16); + private static final int SWAP_POP_DUP = SWAP | (POP << 8) | (DUP << 16); + private static final int SWAP_POP_DUP_X1 = SWAP | (POP << 8) | (DUP_X1 << 16); + private static final int DUP_X2_POP = DUP_X2 | (POP << 8); + private static final int DUP_X2_POP2 = DUP_X2 | (POP2 << 8); + private static final int DUP_X2_POP3_DUP = DUP_X2 | (POP << 8) | (POP2 << 16) | (DUP << 24); + private static final int DUP2_X1_POP = DUP2_X1 | (POP << 8); + private static final int DUP2_X1_POP3_DUP = DUP2_X1 | (POP2 << 8) | (POP << 16) | (DUP << 24); + private static final int DUP2_X1_POP3_DUP_X1 = DUP2_X1 | (POP2 << 8) | (POP << 16) | (DUP_X1 << 24); + private static final int DUP2_X1_POP3_DUP2 = DUP2_X1 | (POP2 << 8) | (POP << 16) | (DUP2 << 24); + private static final int DUP2_X2_POP3 = DUP2_X2 | (POP2 << 8) | (POP << 16); + private static final int DUP2_X2_SWAP_POP = DUP2_X2 | (SWAP << 8) | (POP << 16); private final InstructionUsageMarker instructionUsageMarker; @@ -218,7 +228,7 @@ // Reset the code changes. codeAttributeEditor.reset(codeLength); - // Replace virtual invocations by static invocations, where neceesary. + // Replace virtual invocations by static invocations, where necessary. if (DEBUG) System.out.println("Static invocation fixing:"); codeAttribute.instructionsAccept(clazz, method, @@ -519,7 +529,7 @@ { // Check all stack entries that are popped. // Unusual case: an exception handler with an exception that is - // no longer consumed directly by a method. + // no longer consumed as a method parameter. // Typical case: a freshly marked variable initialization that // requires some value on the stack. int popCount = instruction.stackPopCount(clazz); @@ -535,16 +545,36 @@ for (int stackIndex = stackSize - popCount; stackIndex < stackSize; stackIndex++) { boolean stackEntryUnwantedBefore = - instructionUsageMarker.isStackEntryUnwantedBefore( offset, stackIndex); + instructionUsageMarker.isStackEntryUnwantedBefore(offset, stackIndex); boolean stackEntryPresentBefore = - instructionUsageMarker.isStackEntryPresentBefore( offset, stackIndex); + instructionUsageMarker.isStackEntryPresentBefore(offset, stackIndex); if (stackEntryUnwantedBefore) { if (stackEntryPresentBefore) { - // Remember to pop it. - requiredPopCount++; + // Check if it is an exception pushed by a + // handler (should be) that is not at the + // top of the stack ([PGD-748], test2162). + InstructionOffsetValue producers = + tracedStack.getBottomProducerValue(stackIndex).instructionOffsetValue(); + if (producers.instructionOffsetCount() == 1 && + producers.isExceptionHandler(0) && + stackIndex < stackSize - 1) + { + // Try to handle it. + // This only works if the exception isn't + // consumed elsewhere (should be ok, since + // it's an unused parameter). + if (DEBUG) System.out.println(" Popping exception at handler "+instruction.toString(offset)); + + insertPopInstructions(producers.instructionOffset(0), false, true, 1); + } + else + { + // Remember to pop it. + requiredPopCount++; + } } } else @@ -558,19 +588,21 @@ } // Pop some unnecessary stack entries. + // This only works if the entries are at the top of the stack. if (requiredPopCount > 0) { - if (DEBUG) System.out.println(" Inserting before marked consumer "+instruction.toString(offset)); + if (DEBUG) System.out.println(" Popping "+requiredPopCount+" entries before marked consumer "+instruction.toString(offset)); - insertPopInstructions(offset, false, true, popCount); + insertPopInstructions(offset, false, true, requiredPopCount); } // Push some necessary stack entries. + // This only works if the entries are at the top of the stack. if (requiredPushCount > 0) { Value value = tracedStack.getTop(0); - if (DEBUG) System.out.println(" Inserting before marked consumer "+instruction.toString(offset)); + if (DEBUG) System.out.println(" Pushing type "+value.computationalType()+" entry before marked consumer "+instruction.toString(offset)); if (requiredPushCount > (value.isCategory2() ? 2 : 1)) { @@ -606,7 +638,7 @@ // Pop the unnecessary stack entries. if (requiredPopCount > 0) { - if (DEBUG) System.out.println(" Inserting after marked producer "+instruction.toString(offset)); + if (DEBUG) System.out.println(" Popping "+requiredPopCount+" entries after marked producer "+instruction.toString(offset)); insertPopInstructions(offset, false, false, requiredPopCount); } @@ -640,7 +672,7 @@ // Pop the unnecessary stack entries. if (expectedPopCount > 0) { - if (DEBUG) System.out.println(" Replacing unmarked consumer "+instruction.toString(offset)); + if (DEBUG) System.out.println(" Popping "+expectedPopCount+" entries instead of unmarked consumer "+instruction.toString(offset)); insertPopInstructions(offset, true, false, expectedPopCount); } @@ -671,7 +703,7 @@ // Push some necessary stack entries. if (expectedPushCount > 0) { - if (DEBUG) System.out.println(" Replacing unmarked producer "+instruction.toString(offset)); + if (DEBUG) System.out.println(" Pushing type "+tracedStack.getTop(0).computationalType()+" entry instead of unmarked producer "+instruction.toString(offset)); insertPushInstructions(offset, true, false, tracedStack.getTop(0).computationalType()); } @@ -933,93 +965,93 @@ stackEntryNecessary1 ? stackEntryNecessary2 ? stackEntryNecessary3 ? - stackEntryNecessary0 ? DUP_X2 : // ...XYO -> ...OXYO - MOV_X2 : // ...XYO -> ...OXY + stackEntryNecessary0 ? DUP_X2 : // ...XYO -> ...OXYO + MOV_X2 : // ...XYO -> ...OXY // !stackEntryNecessary3 - stackEntryNecessary0 ? NOP : // ...XYO -> ...XYO - stackEntryPresent0 ? POP : // ...XYO -> ...XY - NOP : // ...XY -> ...XY + stackEntryNecessary0 ? NOP : // ...XYO -> ...XYO + stackEntryPresent0 ? POP : // ...XYO -> ...XY + NOP : // ...XY -> ...XY stackEntryPresent2 ? stackEntryNecessary3 ? - // stackEntryNecessary0 ? UNSUPPORTED : // ...XYO -> ...OYO - UNSUPPORTED : // ...XYO -> ...OY + stackEntryNecessary0 ? DUP2_X1_POP3_DUP_X1 : // ...XYO -> ...OYO + SWAP_DUP2_X1_POP3 : // ...XYO -> ...OY // !stackEntryNecessary3 - stackEntryNecessary0 ? POP_X2 : // ...XYO -> ...YO - stackEntryPresent0 ? POP_SWAP_POP : // ...XYO -> ...Y - POP_X1 : // ...XY -> ...Y + stackEntryNecessary0 ? POP_X2 : // ...XYO -> ...YO + stackEntryPresent0 ? POP_SWAP_POP : // ...XYO -> ...Y + POP_X1 : // ...XY -> ...Y // !stackEntryPresent2 stackEntryNecessary3 ? - stackEntryNecessary0 ? DUP_X1 : // ...YO -> ...OYO - SWAP : // ...YO -> ...OY + stackEntryNecessary0 ? DUP_X1 : // ...YO -> ...OYO + SWAP : // ...YO -> ...OY // !stackEntryNecessary3 - stackEntryNecessary0 ? NOP : // ...YO -> ...YO - stackEntryPresent0 ? POP : // ...YO -> ...Y - NOP : // ...Y -> ...Y + stackEntryNecessary0 ? NOP : // ...YO -> ...YO + stackEntryPresent0 ? POP : // ...YO -> ...Y + NOP : // ...Y -> ...Y stackEntryPresent1 ? stackEntryNecessary2 ? stackEntryNecessary3 ? - stackEntryNecessary0 ? SWAP_POP_DUP_X1 : // ...XYO -> ...OXO - DUP_X2_POP2 : // ...XYO -> ...OX + stackEntryNecessary0 ? SWAP_POP_DUP_X1 : // ...XYO -> ...OXO + DUP_X2_POP2 : // ...XYO -> ...OX // !stackEntryNecessary3 - stackEntryNecessary0 ? POP_X1 : // ...XYO -> ...XO - stackEntryPresent0 ? POP2 : // ...XYO -> ...X - POP : // ...XY -> ...X + stackEntryNecessary0 ? POP_X1 : // ...XYO -> ...XO + stackEntryPresent0 ? POP2 : // ...XYO -> ...X + POP : // ...XY -> ...X stackEntryPresent2 ? stackEntryNecessary3 ? - stackEntryNecessary0 ? UNSUPPORTED : // ...XYO -> ...OO - POP2_X1 : // ...XYO -> ...O + stackEntryNecessary0 ? DUP_X2_POP3_DUP : // ...XYO -> ...OO + POP2_X1 : // ...XYO -> ...O // !stackEntryNecessary3 - stackEntryNecessary0 ? POP2_X1 : // ...XYO -> ...O - stackEntryPresent0 ? POP3 : // ...XYO -> ... - POP2 : // ...XY -> ... + stackEntryNecessary0 ? POP2_X1 : // ...XYO -> ...O + stackEntryPresent0 ? POP3 : // ...XYO -> ... + POP2 : // ...XY -> ... // !stackEntryPresent2 stackEntryNecessary3 ? - stackEntryNecessary0 ? SWAP_POP_DUP : // ...YO -> ...OO - POP_X1 : // ...YO -> ...O + stackEntryNecessary0 ? SWAP_POP_DUP : // ...YO -> ...OO + POP_X1 : // ...YO -> ...O // !stackEntryNecessary3 - stackEntryNecessary0 ? POP_X1 : // ...YO -> ...O - stackEntryPresent0 ? POP2 : // ...YO -> ... - POP : // ...Y -> ... + stackEntryNecessary0 ? POP_X1 : // ...YO -> ...O + stackEntryPresent0 ? POP2 : // ...YO -> ... + POP : // ...Y -> ... // !stackEntryPresent1 stackEntryNecessary2 ? stackEntryNecessary3 ? - stackEntryNecessary0 ? DUP_X1 : // ...XO -> ...OXO - SWAP : // ...XO -> ...OX + stackEntryNecessary0 ? DUP_X1 : // ...XO -> ...OXO + SWAP : // ...XO -> ...OX // !stackEntryNecessary3 - stackEntryNecessary0 ? NOP : // ...XO -> ...XO - stackEntryPresent0 ? POP : // ...XO -> ...X - NOP : // ...X -> ...X + stackEntryNecessary0 ? NOP : // ...XO -> ...XO + stackEntryPresent0 ? POP : // ...XO -> ...X + NOP : // ...X -> ...X stackEntryPresent2 ? stackEntryNecessary3 ? - stackEntryNecessary0 ? SWAP_POP_DUP : // ...XO -> ...OO - POP_X1 : // ...XO -> ...O + stackEntryNecessary0 ? SWAP_POP_DUP : // ...XO -> ...OO + POP_X1 : // ...XO -> ...O // !stackEntryNecessary3 - stackEntryNecessary0 ? POP_X1 : // ...XO -> ...O - stackEntryPresent0 ? POP2 : // ...XO -> ... - POP : // ...X -> ... + stackEntryNecessary0 ? POP_X1 : // ...XO -> ...O + stackEntryPresent0 ? POP2 : // ...XO -> ... + POP : // ...X -> ... // !stackEntryPresent2 stackEntryNecessary3 ? - stackEntryNecessary0 ? DUP : // ...O -> ...OO - NOP : // ...O -> ...O + stackEntryNecessary0 ? DUP : // ...O -> ...OO + NOP : // ...O -> ...O // !stackEntryNecessary3 - stackEntryNecessary0 ? NOP : // ...O -> ...O - stackEntryPresent0 ? POP : // ...O -> ... - NOP; // ... -> ... + stackEntryNecessary0 ? NOP : // ...O -> ...O + stackEntryPresent0 ? POP : // ...O -> ... + NOP; // ... -> ... } private int fixedDup2(int instructionOffset, int topBefore, int topAfter) { boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); - boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, - topBefore - - 1); + boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 1); boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); boolean stackEntryNecessary2 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 2); boolean stackEntryNecessary3 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 3); + // Figure out which stack entries should be moved, + // copied, or removed. return stackEntryNecessary3 ? stackEntryNecessary2 ? @@ -1067,43 +1099,142 @@ private int fixedDup2_x1(int instructionOffset, int topBefore, int topAfter) { - // We're currently assuming the value to be duplicated - // is a long or a double, taking up two slots, or at - // least consistent. - boolean stackEntriesPresent01 = instructionUsageMarker.isStackEntriesPresentBefore(instructionOffset, topBefore, topBefore - 1); - boolean stackEntryPresent2 = instructionUsageMarker.isStackEntryPresentBefore( instructionOffset, topBefore - 2); + boolean stackEntryPresent0 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore); + boolean stackEntryPresent1 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 1); + boolean stackEntryPresent2 = instructionUsageMarker.isStackEntryPresentBefore(instructionOffset, topBefore - 2); - boolean stackEntriesNecessary01 = instructionUsageMarker.isStackEntriesNecessaryAfter(instructionOffset, topAfter, topAfter - 1); - boolean stackEntryNecessary2 = instructionUsageMarker.isStackEntryNecessaryAfter( instructionOffset, topAfter - 2); - boolean stackEntriesNecessary34 = instructionUsageMarker.isStackEntriesNecessaryAfter(instructionOffset, topAfter - 3, topAfter - 4); + boolean stackEntryNecessary0 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter); + boolean stackEntryNecessary1 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 1); + boolean stackEntryNecessary2 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 2); + boolean stackEntryNecessary3 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 3); + boolean stackEntryNecessary4 = instructionUsageMarker.isStackEntryNecessaryAfter(instructionOffset, topAfter - 4); // Figure out which stack entries should be moved, // copied, or removed. return - stackEntryNecessary2 ? - stackEntriesNecessary34 ? - stackEntriesNecessary01 ? DUP2_X1 : // ...XAB -> ...ABXAB - MOV2_X1 : // ...XAB -> ...ABX - // !stackEntriesNecessary34 - stackEntriesNecessary01 ? NOP : // ...XAB -> ...XAB - stackEntriesPresent01 ? POP2 : // ...XAB -> ...X - NOP : // ...X -> ...X - stackEntryPresent2 ? - stackEntriesNecessary34 ? - stackEntriesNecessary01 ? UNSUPPORTED : // ...XAB -> ...ABAB - POP_X2 : // ...XAB -> ...AB - // !stackEntriesNecessary34 - stackEntriesNecessary01 ? DUP2_X1_POP3 : // ...XAB -> ...AB - stackEntriesPresent01 ? POP3 : // ...XAB -> ... - POP : // ...X -> ... - // !stackEntryPresent2 - stackEntriesNecessary34 ? - stackEntriesNecessary01 ? DUP2 : // ...AB -> ...ABAB - NOP : // ...AB -> ...AB - // !stackEntriesNecessary34 - stackEntriesNecessary01 ? NOP : // ...AB -> ...AB - stackEntriesPresent01 ? POP2 : // ...AB -> ... - NOP; // ... -> ... + stackEntryNecessary4 ? + stackEntryNecessary3 ? + stackEntryNecessary2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? DUP2_X1 : // ...XAB -> ...ABXAB + DUP2_X1_POP : // ...XAB -> ...ABXA + // !stackEntryNecessary1 + stackEntryNecessary0 ? UNSUPPORTED : // ...XAB -> ...ABXB + MOV2_X1 : // ...XAB -> ...ABX + stackEntryPresent2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? DUP2_X1_POP3_DUP2 : // ...XAB -> ...ABAB + UNSUPPORTED : // ...XAB -> ...ABA + // !stackEntryNecessary1 + stackEntryNecessary0 ? DUP2_X1_POP3_DUP : // ...XAB -> ...ABB + POP_X2 : // ...XAB -> ...AB + // !stackEntryNecessary2 + stackEntryNecessary1 ? + stackEntryNecessary0 ? DUP2 : // ...AB -> ...ABAB + SWAP_DUP_X1 : // ...AB -> ...ABA + // !stackEntryNecessary1 + stackEntryNecessary0 ? DUP : // ...AB -> ...ABB + NOP : // ...AB -> ...AB + // !stackEntryNecessary3 + stackEntryNecessary2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? UNSUPPORTED : // ...XAB -> ...AXAB + stackEntryPresent0 ? POP_DUP_X1 : // ...XAB -> ...AXA + DUP_X1 : // ...XA -> ...AXA + // !stackEntryNecessary1 + stackEntryNecessary0 ? UNSUPPORTED : // ...XAB -> ...AXB + stackEntryPresent0 ? POP_SWAP : // ...XAB -> ...AX + SWAP : // ...XA -> ...AX + stackEntryPresent2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? UNSUPPORTED : // ...XAB -> ...AAB + stackEntryPresent0 ? POP_SWAP_POP_DUP : // ...XAB -> ...AA + SWAP_POP_DUP : // ...XA -> ...AA + // !stackEntryNecessary1 + stackEntryNecessary0 ? POP_X2 : // ...XAB -> ...AB + stackEntryPresent0 ? POP_SWAP_POP : // ...XAB -> ...A + POP_X1 : // ...XA -> ...A + // !stackEntryNecessary2 + stackEntryNecessary1 ? + stackEntryNecessary0 ? SWAP_DUP_X1_SWAP : // ...AB -> ...AAB + stackEntryPresent0 ? POP_DUP : // ...AB -> ...AA + DUP : // ...A -> ...AA + // !stackEntryNecessary1 + stackEntryNecessary0 ? NOP : // ...AB -> ...AB + stackEntryPresent0 ? POP : // ...AB -> ...A + NOP : // ...A -> ...A + // !stackEntryNecessary4 + stackEntryNecessary3 ? + stackEntryNecessary2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? DUP_X2 : // ...XAB -> ...BXAB + DUP_X2_POP : // ...XAB -> ...BXA + stackEntryPresent1 ? + stackEntryNecessary0 ? SWAP_POP_DUP_X1 : // ...XAB -> ...BXB + DUP_X2_POP2 : // ...XAB -> ...BX + // !stackEntryNecessary1 + stackEntryNecessary0 ? POP_X2 : // ...XB -> ...BXB + SWAP : // ...XB -> ...BX + stackEntryPresent2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? DUP2_X1_POP3_DUP_X1 : // ...XAB -> ...BAB + SWAP_DUP_X1_POP3 : // ...XAB -> ...BA + stackEntryPresent1 ? + stackEntryNecessary0 ? DUP_X2_POP3_DUP : // ...XAB -> ...BB + POP2_X1 : // ...XAB -> ...B + // !stackEntryNecessary1 + stackEntryNecessary0 ? SWAP_POP_DUP : // ...XB -> ...BB + POP_X1 : // ...XB -> ...B + // !stackEntryNecessary2 + stackEntryNecessary1 ? + stackEntryNecessary0 ? DUP_X1 : // ...AB -> ...BAB + SWAP : // ...AB -> ...BA + stackEntryPresent1 ? + stackEntryNecessary0 ? SWAP_POP_DUP : // ...AB -> ...BB + POP_X1 : // ...AB -> ...B + // !stackEntryNecessary1 + stackEntryNecessary0 ? DUP : // ...B -> ...BB + NOP : // ...B -> ...B + // !stackEntryNecessary3 + stackEntryNecessary2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? NOP : // ...XAB -> ...XAB + stackEntryPresent0 ? POP : // ...XAB -> ...XA + NOP : // ...XA -> ...XA + stackEntryPresent1 ? + stackEntryNecessary0 ? POP_X1 : // ...XAB -> ...XB + stackEntryPresent0 ? POP2 : // ...XAB -> ...X + POP : // ...XA -> ...X + // !stackEntryNecessary1 + stackEntryNecessary0 ? NOP : // ...XB -> ...XB + stackEntryPresent0 ? POP : // ...XB -> ...X + NOP : // ...X -> ...X + stackEntryPresent2 ? + stackEntryNecessary1 ? + stackEntryNecessary0 ? POP_X2 : // ...XAB -> ...AB + stackEntryPresent0 ? POP_SWAP_POP : // ...XAB -> ...A + POP_X1 : // ...XA -> ...A + stackEntryPresent1 ? + stackEntryNecessary0 ? POP2_X1 : // ...XAB -> ...B + stackEntryPresent0 ? POP3 : // ...XAB -> ... + POP2 : // ...XA -> ... + // !stackEntryNecessary1 + stackEntryNecessary0 ? POP_X1 : // ...XB -> ...B + stackEntryPresent0 ? POP2 : // ...XB -> ... + POP : // ...X -> ... + // !stackEntryNecessary2 + stackEntryNecessary1 ? + stackEntryNecessary0 ? NOP : // ...AB -> ...AB + stackEntryPresent0 ? POP : // ...AB -> ...A + NOP : // ...A -> ...A + stackEntryPresent1 ? + stackEntryNecessary0 ? POP_X1 : // ...AB -> ...B + stackEntryPresent0 ? POP2 : // ...AB -> ... + POP : // ...A -> ... + // !stackEntryNecessary1 + stackEntryNecessary0 ? NOP : // ...B -> ...B + stackEntryPresent0 ? POP : // ...B -> ... + NOP; // ... -> ... } @@ -1127,77 +1258,77 @@ stackEntryNecessary2 ? stackEntryNecessary3 ? stackEntriesNecessary45 ? - stackEntriesNecessary01 ? DUP2_X2 : // ...XYAB -> ...ABXYAB - MOV2_X2 : // ...XYAB -> ...ABXY + stackEntriesNecessary01 ? DUP2_X2 : // ...XYAB -> ...ABXYAB + MOV2_X2 : // ...XYAB -> ...ABXY // !stackEntriesNecessary45 - stackEntriesNecessary01 ? NOP : // ...XYAB -> ...XYAB - stackEntriesPresent01 ? POP2 : // ...XYAB -> ...XY - NOP : // ...XY -> ...XY + stackEntriesNecessary01 ? NOP : // ...XYAB -> ...XYAB + stackEntriesPresent01 ? POP2 : // ...XYAB -> ...XY + NOP : // ...XY -> ...XY stackEntryPresent3 ? stackEntriesNecessary45 ? - stackEntriesNecessary01 ? UNSUPPORTED : // ...XYAB -> ...ABYAB - DUP2_X2_SWAP_POP : // ...XYAB -> ...ABY + stackEntriesNecessary01 ? UNSUPPORTED : // ...XYAB -> ...ABYAB + DUP2_X2_SWAP_POP : // ...XYAB -> ...ABY // !stackEntriesNecessary45 - stackEntriesNecessary01 ? POP_X3 : // ...XYAB -> ...YAB - stackEntriesPresent01 ? POP2_SWAP_POP : // ...XYAB -> ...Y - POP_X1 : // ...XY -> ...Y + stackEntriesNecessary01 ? POP_X3 : // ...XYAB -> ...YAB + stackEntriesPresent01 ? POP2_SWAP_POP : // ...XYAB -> ...Y + POP_X1 : // ...XY -> ...Y // !stackEntryPresent3 stackEntriesNecessary45 ? - stackEntriesNecessary01 ? DUP2_X1 : // ...YAB -> ...ABYAB - MOV2_X1 : // ...YAB -> ...ABY + stackEntriesNecessary01 ? DUP2_X1 : // ...YAB -> ...ABYAB + MOV2_X1 : // ...YAB -> ...ABY // !stackEntriesNecessary45 - stackEntriesNecessary01 ? NOP : // ...YAB -> ...YAB - stackEntriesPresent01 ? POP2 : // ...YAB -> ...Y - NOP : // ...Y -> ...Y + stackEntriesNecessary01 ? NOP : // ...YAB -> ...YAB + stackEntriesPresent01 ? POP2 : // ...YAB -> ...Y + NOP : // ...Y -> ...Y stackEntryPresent2 ? stackEntryNecessary3 ? stackEntriesNecessary45 ? - stackEntriesNecessary01 ? UNSUPPORTED : // ...XYAB -> ...ABXAB - DUP2_X2_POP3 : // ...XYAB -> ...ABX + stackEntriesNecessary01 ? UNSUPPORTED : // ...XYAB -> ...ABXAB + DUP2_X2_POP3 : // ...XYAB -> ...ABX // !stackEntriesNecessary45 - stackEntriesNecessary01 ? POP_X2 : // ...XYAB -> ...XAB - stackEntriesPresent01 ? POP3 : // ...XYAB -> ...X - POP : // ...XY -> ...X + stackEntriesNecessary01 ? POP_X2 : // ...XYAB -> ...XAB + stackEntriesPresent01 ? POP3 : // ...XYAB -> ...X + POP : // ...XY -> ...X stackEntryPresent3 ? stackEntriesNecessary45 ? - stackEntriesNecessary01 ? UNSUPPORTED : // ...XYAB -> ...ABAB - POP2_X2 : // ...XYAB -> ...AB + stackEntriesNecessary01 ? UNSUPPORTED : // ...XYAB -> ...ABAB + POP2_X2 : // ...XYAB -> ...AB // !stackEntriesNecessary45 - stackEntriesNecessary01 ? POP2_X2 : // ...XYAB -> ...AB - stackEntriesPresent01 ? POP4 : // ...XYAB -> ... - POP2 : // ...XY -> ... + stackEntriesNecessary01 ? POP2_X2 : // ...XYAB -> ...AB + stackEntriesPresent01 ? POP4 : // ...XYAB -> ... + POP2 : // ...XY -> ... // !stackEntryPresent3 stackEntriesNecessary45 ? - stackEntriesNecessary01 ? UNSUPPORTED : // ...YAB -> ...ABAB - POP_X2 : // ...YAB -> ...AB + stackEntriesNecessary01 ? DUP2_X1_POP3_DUP2 : // ...YAB -> ...ABAB + POP_X2 : // ...YAB -> ...AB // !stackEntriesNecessary45 - stackEntriesNecessary01 ? POP_X2 : // ...YAB -> ...AB - stackEntriesPresent01 ? POP3 : // ...YAB -> ... - POP : // ...Y -> ... + stackEntriesNecessary01 ? POP_X2 : // ...YAB -> ...AB + stackEntriesPresent01 ? POP3 : // ...YAB -> ... + POP : // ...Y -> ... // !stackEntryPresent2 stackEntryNecessary3 ? stackEntriesNecessary45 ? - stackEntriesNecessary01 ? DUP2_X1 : // ...XAB -> ...ABXAB - MOV2_X1 : // ...XAB -> ...ABX + stackEntriesNecessary01 ? DUP2_X1 : // ...XAB -> ...ABXAB + MOV2_X1 : // ...XAB -> ...ABX // !stackEntriesNecessary45 - stackEntriesNecessary01 ? NOP : // ...XAB -> ...XAB - stackEntriesPresent01 ? POP2 : // ...XAB -> ...X - NOP : // ...X -> ...X + stackEntriesNecessary01 ? NOP : // ...XAB -> ...XAB + stackEntriesPresent01 ? POP2 : // ...XAB -> ...X + NOP : // ...X -> ...X stackEntryPresent3 ? stackEntriesNecessary45 ? - stackEntriesNecessary01 ? UNSUPPORTED : // ...XAB -> ...ABAB - POP_X2 : // ...XAB -> ...AB + stackEntriesNecessary01 ? DUP2_X1_POP3_DUP2 : // ...XAB -> ...ABAB + POP_X2 : // ...XAB -> ...AB // !stackEntriesNecessary45 - stackEntriesNecessary01 ? POP_X2 : // ...XAB -> ...AB - stackEntriesPresent01 ? POP3 : // ...XAB -> ... - POP : // ...X -> ... + stackEntriesNecessary01 ? POP_X2 : // ...XAB -> ...AB + stackEntriesPresent01 ? POP3 : // ...XAB -> ... + POP : // ...X -> ... // !stackEntryPresent3 stackEntriesNecessary45 ? - stackEntriesNecessary01 ? DUP2 : // ...AB -> ...ABAB - NOP : // ...AB -> ...AB + stackEntriesNecessary01 ? DUP2 : // ...AB -> ...ABAB + NOP : // ...AB -> ...AB // !stackEntriesNecessary45 - stackEntriesNecessary01 ? NOP : // ...AB -> ...AB - stackEntriesPresent01 ? POP2 : // ...AB -> ... + stackEntriesNecessary01 ? NOP : // ...AB -> ...AB + stackEntriesPresent01 ? POP2 : // ...AB -> ... NOP; // ... -> ... } diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/EvaluationSimplifier.java proguard-6.2.0/core/src/proguard/optimize/evaluation/EvaluationSimplifier.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/EvaluationSimplifier.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/EvaluationSimplifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/InitializationFinder.java proguard-6.2.0/core/src/proguard/optimize/evaluation/InitializationFinder.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/InitializationFinder.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/InitializationFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/InstructionUsageMarker.java proguard-6.2.0/core/src/proguard/optimize/evaluation/InstructionUsageMarker.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/InstructionUsageMarker.java 2018-02-18 17:40:12.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/InstructionUsageMarker.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -41,6 +41,14 @@ * This AttributeVisitor marks necessary instructions in the code attributes * that it visits, based on partial evaluation. * + * @see NoSideEffectClassMarker + * @see SideEffectClassMarker + * @see ReadWriteFieldMarker + * @see NoSideEffectMethodMarker + * @see NoExternalSideEffectMethodMarker + * @see SideEffectMethodMarker + * @see ParameterEscapeMarker + * * @author Eric Lafortune */ public class InstructionUsageMarker @@ -55,16 +63,16 @@ private static boolean DEBUG_RESULTS = DEBUG; //*/ - private final PartialEvaluator partialEvaluator; - private final boolean runPartialEvaluator; - private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator(new TypedReferenceValueFactory()); - private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true, true); - private final MyParameterUsageMarker parameterUsageMarker = new MyParameterUsageMarker(); - private final MyInitialUsageMarker initialUsageMarker = new MyInitialUsageMarker(); - private final MyProducerMarker producerMarker = new MyProducerMarker(); - private final MyVariableInitializationMarker variableInitializationMarker = new MyVariableInitializationMarker(); - private final MyStackConsistencyMarker stackConsistencyMarker = new MyStackConsistencyMarker(); - private final MyExtraPopInstructionMarker extraPopInstructionMarker = new MyExtraPopInstructionMarker(); + private final PartialEvaluator partialEvaluator; + private final boolean runPartialEvaluator; + private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator(new TypedReferenceValueFactory()); + private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true, true); + private final MyParameterUsageMarker parameterUsageMarker = new MyParameterUsageMarker(); + private final MyInitialUsageMarker initialUsageMarker = new MyInitialUsageMarker(); + private final MyProducerMarker producerMarker = new MyProducerMarker(); + private final MyVariableInitializationMarker variableInitializationMarker = new MyVariableInitializationMarker(); + private final MyStackConsistencyMarker stackConsistencyMarker = new MyStackConsistencyMarker(); + private final MyExtraPushPopInstructionMarker extraPushPopInstructionMarker = new MyExtraPushPopInstructionMarker(); private InstructionOffsetValue[] reverseDependencies = new InstructionOffsetValue[ClassConstants.TYPICAL_CODE_LENGTH]; @@ -505,7 +513,7 @@ Instruction instruction = InstructionFactory.create(codeAttribute.code, offset); - instruction.accept(clazz, method, codeAttribute, offset, extraPopInstructionMarker); + instruction.accept(clazz, method, codeAttribute, offset, extraPushPopInstructionMarker); // Check if this instruction is a branch origin from a branch // that straddles some marked code. @@ -705,7 +713,17 @@ break; case InstructionConstants.OP_PUTFIELD: - createReverseDependencies(clazz, offset, constantInstruction); + // We generally have to mark the putfield instruction, + // unless it's never read. We can reverse the dependencies + // if it's a field of a recently created instance. + if (sideEffectInstructionChecker.hasSideEffects(clazz, + method, + codeAttribute, + offset, + constantInstruction)) + { + createReverseDependencies(clazz, offset, constantInstruction); + } break; case InstructionConstants.OP_INVOKEVIRTUAL: @@ -1116,10 +1134,10 @@ /** - * This InstructionVisitor marks unnecessary popping instructions that - * should still pop some values to keep the stack consistent. + * This InstructionVisitor marks instructions that should still push or + * pop some values to keep the stack consistent. */ - private class MyExtraPopInstructionMarker + private class MyExtraPushPopInstructionMarker extends SimplifiedVisitor implements InstructionVisitor { @@ -1143,20 +1161,14 @@ if (!isStackEntryUnwantedBefore(offset, stackIndex) && isStackEntryPresentBefore(offset, stackIndex)) { - // Is it already a pop instruction? - if (isPop(instruction)) - { - // Just mark it as necessary, along with the stack - // entries at the producer offsets. This might happen - // in Kotlin code [DGD-481], with getstatic/pop. - markInstruction(offset); - markStackEntryProducers(offset, stackIndex, false); - } - else - { - // Mark that we'll need an extra pop instruction. - markExtraPushPopInstruction(offset); - } + // Mark that we'll need an extra pop instruction. + markExtraPushPopInstruction(offset); + + // [DGD-481][DGD-504] Mark the stack entries and + // their producers again for a push/pop. In Kotlin + // code, it can happen that we have missed a producer + // during stack consistency marking. + markStackEntryProducers(offset, stackIndex, false); } } } @@ -1166,16 +1178,6 @@ // Small utility methods. /** - * Returns whether the given instruction is a pop instruction. - */ - private boolean isPop(Instruction instruction) - { - return instruction.opcode == InstructionConstants.OP_POP || - instruction.opcode == InstructionConstants.OP_POP2; - } - - - /** * Marks the producing instructions of the variable consumer at the given * offset. * @param consumerOffset the offset of the variable consumer. @@ -1214,40 +1216,45 @@ * @param variableIndex the index of the variable. * @param visitedOffsets the already visited consumer offsets, needed to * prevent infinite loops. + * @return the updated visited consumer offsets. */ - private void markVariableInitializersBefore(int consumerOffset, - int variableIndex, - InstructionOffsetValue visitedOffsets) + private InstructionOffsetValue markVariableInitializersBefore(int consumerOffset, + int variableIndex, + InstructionOffsetValue visitedOffsets) { // Avoid infinite loops by stopping recursion if we encounter // an already visited offset. - if (visitedOffsets != null && - visitedOffsets.contains(consumerOffset)) + if (visitedOffsets == null || + !visitedOffsets.contains(consumerOffset)) { - return; - } - - visitedOffsets = visitedOffsets == null ? - new InstructionOffsetValue(consumerOffset) : - visitedOffsets.add(consumerOffset); - - // Make sure the variable is initialized after all producers. - // Use the simple evaluator, to get the JVM's view of what is - // initialized. - InstructionOffsetValue producerOffsets = - simplePartialEvaluator.getVariablesBefore(consumerOffset).getProducerValue(variableIndex).instructionOffsetValue(); + visitedOffsets = visitedOffsets == null ? + new InstructionOffsetValue(consumerOffset) : + visitedOffsets.add(consumerOffset); + + // Make sure the variable is initialized after all producers. + // Use the simple evaluator, to get the JVM's view of what is + // initialized. + InstructionOffsetValue producerOffsets = + simplePartialEvaluator.getVariablesBefore(consumerOffset).getProducerValue(variableIndex).instructionOffsetValue(); - int offsetCount = producerOffsets.instructionOffsetCount(); - for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++) - { - if (!producerOffsets.isMethodParameter(offsetIndex) && - !producerOffsets.isExceptionHandler(offsetIndex)) + int offsetCount = producerOffsets.instructionOffsetCount(); + for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++) { - int producerOffset = - producerOffsets.instructionOffset(offsetIndex); - markVariableInitializersAfter(producerOffset, variableIndex, visitedOffsets); + if (!producerOffsets.isMethodParameter(offsetIndex) && + !producerOffsets.isExceptionHandler(offsetIndex)) + { + int producerOffset = + producerOffsets.instructionOffset(offsetIndex); + + visitedOffsets = + markVariableInitializersAfter(producerOffset, + variableIndex, + visitedOffsets); + } } } + + return visitedOffsets; } @@ -1259,10 +1266,11 @@ * @param variableIndex the index of the variable. * @param visitedOffsets the already visited consumer offsets, needed to * prevent infinite loops. + * @return the updated visited consumer offsets. */ - private void markVariableInitializersAfter(int producerOffset, - int variableIndex, - InstructionOffsetValue visitedOffsets) + private InstructionOffsetValue markVariableInitializersAfter(int producerOffset, + int variableIndex, + InstructionOffsetValue visitedOffsets) { // No problem if the producer has already been marked. if (!isInstructionNecessary(producerOffset)) @@ -1282,9 +1290,14 @@ // Don't mark the producer, but recursively look at the // preceding producers of the same variable. Their values // will fall through, replacing this producer. - markVariableInitializersBefore(producerOffset, variableIndex, visitedOffsets); + visitedOffsets = + markVariableInitializersBefore(producerOffset, + variableIndex, + visitedOffsets); } } + + return visitedOffsets; } diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/LivenessAnalyzer.java proguard-6.2.0/core/src/proguard/optimize/evaluation/LivenessAnalyzer.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/LivenessAnalyzer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/LivenessAnalyzer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/LoadingInvocationUnit.java proguard-6.2.0/core/src/proguard/optimize/evaluation/LoadingInvocationUnit.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/LoadingInvocationUnit.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/LoadingInvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/ParameterTracingInvocationUnit.java proguard-6.2.0/core/src/proguard/optimize/evaluation/ParameterTracingInvocationUnit.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/ParameterTracingInvocationUnit.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/ParameterTracingInvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/PartialEvaluator.java proguard-6.2.0/core/src/proguard/optimize/evaluation/PartialEvaluator.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/PartialEvaluator.java 2018-05-03 13:36:32.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/PartialEvaluator.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/ReferenceTracingInvocationUnit.java proguard-6.2.0/core/src/proguard/optimize/evaluation/ReferenceTracingInvocationUnit.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/ReferenceTracingInvocationUnit.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/ReferenceTracingInvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/ReferenceTracingValueFactory.java proguard-6.2.0/core/src/proguard/optimize/evaluation/ReferenceTracingValueFactory.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/ReferenceTracingValueFactory.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/ReferenceTracingValueFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -195,6 +195,12 @@ } + public IntegerValue createIntegerValue(int min, int max) + { + return valueFactory.createIntegerValue(min, max); + } + + public LongValue createLongValue() { return valueFactory.createLongValue(); diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumArrayPropagator.java proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumArrayPropagator.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumArrayPropagator.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumArrayPropagator.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumClassChecker.java proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumClassChecker.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumClassChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumClassChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumClassSimplifier.java proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumClassSimplifier.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumClassSimplifier.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumClassSimplifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumDescriptorSimplifier.java proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumDescriptorSimplifier.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumDescriptorSimplifier.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumDescriptorSimplifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumUseChecker.java proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumUseChecker.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumUseChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumUseChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -23,7 +23,7 @@ import proguard.classfile.*; import proguard.classfile.attribute.*; import proguard.classfile.attribute.visitor.*; -import proguard.classfile.constant.ClassConstant; +import proguard.classfile.constant.*; import proguard.classfile.constant.visitor.ConstantVisitor; import proguard.classfile.instruction.*; import proguard.classfile.instruction.visitor.InstructionVisitor; @@ -46,8 +46,9 @@ implements ClassVisitor, MemberVisitor, AttributeVisitor, - InstructionVisitor, + BootstrapMethodInfoVisitor, ConstantVisitor, + InstructionVisitor, ParameterVisitor { //* @@ -92,6 +93,9 @@ public void visitProgramClass(ProgramClass programClass) { + // Unmark the simple enum classes in bootstrap methods attributes. + programClass.attributesAccept(this); + if ((programClass.getAccessFlags() & ClassConstants.ACC_ANNOTATION) != 0) { // Unmark the simple enum classes in annotations. @@ -110,6 +114,13 @@ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute) + { + // Unmark the simple enum classes in all bootstrap methods. + bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this); + } + + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { // Evaluate the method. @@ -139,6 +150,59 @@ } + // Implementations for BootstrapMethodInfoVisitor. + + public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo) + { + // Unmark the simple enum classes referenced in the method handle. + bootstrapMethodInfo.methodHandleAccept(clazz, this); + + // Unmark the simple enum classes referenced in the method arguments. + bootstrapMethodInfo.methodArgumentsAccept(clazz, this); + } + + + // Implementations for ConstantVisitor. + + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + public void visitStringConstant(Clazz clazz, StringConstant stringConstant) + { + // Unmark any simple enum class referenced in the string constant. + stringConstant.referencedClassAccept(complexEnumMarker); + } + + + public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) + { + // Unmark the simple enum classes referenced in the method handle + // (through a reference constant). + methodHandleConstant.referenceAccept(clazz, this); + } + + + public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) + { + // Unmark the simple enum classes referenced in the method type constant. + methodTypeConstant.referencedClassesAccept(referencedComplexEnumMarker); + } + + + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) + { + // Unmark the simple enum classes referenced in the reference. + refConstant.referencedClassAccept(referencedComplexEnumMarker); + } + + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + // Unmark any simple enum class referenced in the class constant. + classConstant.referencedClassAccept(complexEnumMarker); + } + + // Implementations for InstructionVisitor. public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction) diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumUseSimplifier.java proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumUseSimplifier.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/SimpleEnumUseSimplifier.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/SimpleEnumUseSimplifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -152,8 +152,7 @@ replaceInstruction(clazz, offset, simpleInstruction, - new SimpleInstruction( - InstructionConstants.OP_IALOAD)); + new SimpleInstruction(InstructionConstants.OP_IALOAD)); } break; } @@ -360,6 +359,10 @@ branchInstruction, new BranchInstruction(InstructionConstants.OP_IFICMPEQ, branchInstruction.branchOffset)); + + // Replace any producers of null constants. + replaceNullStackEntryProducers(clazz, method, codeAttribute, offset, 0); + replaceNullStackEntryProducers(clazz, method, codeAttribute, offset, 1); } break; } @@ -373,6 +376,10 @@ branchInstruction, new BranchInstruction(InstructionConstants.OP_IFICMPNE, branchInstruction.branchOffset)); + + // Replace any producers of null constants. + replaceNullStackEntryProducers(clazz, method, codeAttribute, offset, 0); + replaceNullStackEntryProducers(clazz, method, codeAttribute, offset, 1); } break; } @@ -444,10 +451,10 @@ int stackEntryIndex = parameterSize - parameterOffset - 1; replaceNullStackEntryProducers(invocationClazz, - invocationMethod, - invocationCodeAttribute, - invocationOffset, - stackEntryIndex); + invocationMethod, + invocationCodeAttribute, + invocationOffset, + stackEntryIndex); } } @@ -755,8 +762,9 @@ /** - * Replaces aconst_null producers of the specified stack entry by - * iconst_0. + * Turn null reference producers of the specified stack entry into 0 int + * producers. The partial evaluator generally can't identify them as + * simple enums. */ private void replaceNullStackEntryProducers(Clazz clazz, Method method, @@ -769,25 +777,55 @@ for (int index = 0; index < producerOffsets.instructionOffsetCount(); index++) { + // Is the producer always pushing null? int producerOffset = producerOffsets.instructionOffset(index); - - // TODO: A method might be pushing the null constant. if (producerOffset >= 0 && - codeAttribute.code[producerOffset] == InstructionConstants.OP_ACONST_NULL) + partialEvaluator.getStackAfter(producerOffset).getTop(0).referenceValue().isNull() == Value.ALWAYS) { - // Replace pushing null by pushing 0. - replaceInstruction(clazz, - producerOffset, - new SimpleInstruction(InstructionConstants.OP_ACONST_NULL), - new SimpleInstruction(InstructionConstants.OP_ICONST_0)); + Instruction producerInstruction = + InstructionFactory.create(codeAttribute.code[producerOffset]); + + // Is it a simple case? + switch (producerInstruction.opcode) + { + case InstructionConstants.OP_ACONST_NULL: + case InstructionConstants.OP_ALOAD: + case InstructionConstants.OP_ALOAD_0: + case InstructionConstants.OP_ALOAD_1: + case InstructionConstants.OP_ALOAD_2: + case InstructionConstants.OP_ALOAD_3: + { + // Replace pushing null by pushing 0. + replaceInstruction(clazz, + producerOffset, + producerInstruction, + new SimpleInstruction(InstructionConstants.OP_ICONST_0)); + break; + } + default: + { + // Otherwise pop the null and then push 0. + replaceInstructions(clazz, + producerOffset, + producerInstruction, + new Instruction[] + { + producerInstruction, + new SimpleInstruction(InstructionConstants.OP_POP), + new SimpleInstruction(InstructionConstants.OP_ICONST_0) + }); + break; + } + } } } } /** - * Replaces aconst_null/astore producers of the specified reference variable by - * iconst_0/istore. + * Turn null reference producers of the specified reference variable into + * 0 int producers. The partial evaluator generally can't identify them + * as simple enums. */ private void replaceNullVariableProducers(Clazz clazz, Method method, @@ -803,11 +841,12 @@ if (!producerOffsets.isMethodParameter(index) && !producerOffsets.isExceptionHandler(index)) { + // Is the producer always storing null? int producerOffset = producerOffsets.instructionOffset(index); - if (partialEvaluator.getVariablesAfter(producerOffset).getValue(variableIndex).referenceValue().isNull() == Value.ALWAYS) { - // Replace loading null by loading 0. + // Replace storing the null reference value by storing an + // int value. replaceInstruction(clazz, producerOffset, new VariableInstruction(InstructionConstants.OP_ASTORE, variableIndex), diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/StoringInvocationUnit.java proguard-6.2.0/core/src/proguard/optimize/evaluation/StoringInvocationUnit.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/StoringInvocationUnit.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/StoringInvocationUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/TracedBranchUnit.java proguard-6.2.0/core/src/proguard/optimize/evaluation/TracedBranchUnit.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/TracedBranchUnit.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/TracedBranchUnit.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/evaluation/VariableOptimizer.java proguard-6.2.0/core/src/proguard/optimize/evaluation/VariableOptimizer.java --- proguard-6.0.3/core/src/proguard/optimize/evaluation/VariableOptimizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/evaluation/VariableOptimizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/DuplicateJsonFieldNameChecker.java proguard-6.2.0/core/src/proguard/optimize/gson/DuplicateJsonFieldNameChecker.java --- proguard-6.0.3/core/src/proguard/optimize/gson/DuplicateJsonFieldNameChecker.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/DuplicateJsonFieldNameChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.visitor.*; + +import java.util.*; + +/** + * This class visitor checks whether the visited class has duplicate field names + * in its JSON representation. + * + * @author Lars Vandenbergh + */ +class DuplicateJsonFieldNameChecker +implements ClassVisitor +{ + public boolean hasDuplicateJsonFieldNames; + + + // Implementations for ClassVisitor. + + @Override + public void visitProgramClass(ProgramClass programClass) + { + for (OptimizedJsonFieldCollector.Mode mode : OptimizedJsonFieldCollector.Mode.values()) + { + OptimizedJsonInfo optimizedJsonInfo = new OptimizedJsonInfo(); + OptimizedJsonFieldCollector jsonFieldCollector = + new OptimizedJsonFieldCollector(optimizedJsonInfo, + mode); + programClass.accept(new MultiClassVisitor( + jsonFieldCollector, + new AllFieldVisitor(jsonFieldCollector))); + + OptimizedJsonInfo.ClassJsonInfo classJsonInfo = + optimizedJsonInfo.classJsonInfos.get(programClass.getName()); + Collection jsonFieldNamesCollection = + classJsonInfo.javaToJsonFieldNames.values(); + Set uniqueFieldNames = new HashSet(); + for (String[] jsonFieldNames : jsonFieldNamesCollection) + { + for (String jsonFieldName : jsonFieldNames) + { + if (uniqueFieldNames.contains(jsonFieldName)) + { + hasDuplicateJsonFieldNames = true; + return; + } + else + { + uniqueFieldNames.add(jsonFieldName); + } + } + } + } + } + + @Override + public void visitLibraryClass(LibraryClass libraryClass) {} +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/FieldSignatureCollector.java proguard-6.2.0/core/src/proguard/optimize/gson/FieldSignatureCollector.java --- proguard-6.0.3/core/src/proguard/optimize/gson/FieldSignatureCollector.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/FieldSignatureCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This visitor collects the Signature attribute of a Field. + */ +class FieldSignatureCollector +extends SimplifiedVisitor +implements AttributeVisitor +{ + private String fieldSignature; + + + public String getFieldSignature() + { + return fieldSignature; + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitSignatureAttribute(Clazz clazz, + Field field, + SignatureAttribute signatureAttribute) + { + this.fieldSignature = signatureAttribute.getSignature(clazz); + } + +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonAnnotationCleaner.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonAnnotationCleaner.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonAnnotationCleaner.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonAnnotationCleaner.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.visitor.AllAttributeVisitor; +import proguard.classfile.visitor.*; + +/** + * This class visitor removes Gson annotations that are not required anymore + * after the Gson optimizations are applied. + * + * @author Rob Coekaerts + * @author Lars Vandenbergh + */ +public class GsonAnnotationCleaner +implements ClassVisitor +{ + + private final GsonRuntimeSettings gsonRuntimeSettings; + + + /** + * Creates a new GsonAnnotationCleaner. + * + * @param gsonRuntimeSettings keeps track of all GsonBuilder invocations. + */ + public GsonAnnotationCleaner(GsonRuntimeSettings gsonRuntimeSettings) + { + this.gsonRuntimeSettings = gsonRuntimeSettings; + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + final Object mark = new Object(); + + // Mark annotations when we are sure that they are not required + // anymore by GSON. + if (!gsonRuntimeSettings.setFieldNamingPolicy && + !gsonRuntimeSettings.setFieldNamingStrategy) + { + programClass.fieldsAccept( + new AllAttributeVisitor( + new AllAnnotationVisitor( + new AnnotationTypeFilter(GsonClassConstants.ANNOTATION_TYPE_SERIALIZED_NAME, + new VisitorInfoSetter(mark))))); + } + + programClass.fieldsAccept( + new AllAttributeVisitor( + new AllAnnotationVisitor( + new AnnotationTypeFilter(GsonClassConstants.ANNOTATION_TYPE_EXPOSE, + new VisitorInfoSetter(mark))))); + + // Remove marked annotations. + programClass.fieldsAccept( + new AllAttributeVisitor( + new MarkedAnnotationDeleter(mark))); + + // Unmark all annotations on fields. + programClass.fieldsAccept( + new AllAttributeVisitor( + new AllAnnotationVisitor( + new VisitorInfoSetter(null)))); + } + + + public void visitLibraryClass(LibraryClass libraryClass) {} +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonBuilderInvocationFinder.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonBuilderInvocationFinder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonBuilderInvocationFinder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonBuilderInvocationFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,533 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.Constant; +import proguard.classfile.editor.InstructionSequenceBuilder; +import proguard.classfile.instruction.Instruction; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.evaluation.BasicInvocationUnit; +import proguard.evaluation.value.*; +import proguard.optimize.evaluation.PartialEvaluator; + +/** + * This instructor visitor searches for invocations to GsonBuilder and keeps + * track of which parameters of the GsonBuilder are being utilized in the code + * in a GsonRuntimeSettings instance. + * + * @author Joachim Vandersmissen + * @author Lars Vandenbergh + */ +public class GsonBuilderInvocationFinder +extends SimplifiedVisitor +implements InstructionVisitor +{ + private final InstructionSequenceMatcher setVersionMatcher; + private final InstructionSequenceMatcher excludeFieldsWithModifiersMatcher; + private final InstructionSequenceMatcher generateNonExecutableJsonMatcher; + private final InstructionSequenceMatcher excludeFieldsWithoutExposeAnnotationMatcher; + private final InstructionSequenceMatcher serializeNullsMatcher; + private final InstructionSequenceMatcher disableInnerClassSerializationMatcher; + private final InstructionSequenceMatcher setLongSerializationPolicyMatcher; + private final InstructionSequenceMatcher setFieldNamingPolicyMatcher; + private final InstructionSequenceMatcher setFieldNamingStrategyMatcher; + private final InstructionSequenceMatcher setExclusionStrategiesMatcher; + private final InstructionSequenceMatcher addSerializationExclusionStrategyMatcher; + private final InstructionSequenceMatcher addDeserializationExclusionStrategyMatcher; + private final InstructionSequenceMatcher registerTypeAdapterMatcher; + private final InstructionSequenceMatcher registerTypeHierachyAdapterMatcher; + private final InstructionSequenceMatcher serializeSpecialFloatingPointValuesMatcher; + private final TypedReferenceValueFactory valueFactory = + new TypedReferenceValueFactory(); + private final PartialEvaluator partialEvaluator = + new PartialEvaluator(valueFactory, + new BasicInvocationUnit(new TypedReferenceValueFactory()), + true); + private final AttributeVisitor lazyPartialEvaluator = + new AttributeNameFilter(ClassConstants.ATTR_Code, + new SingleTimeAttributeVisitor( + partialEvaluator)); + private final ClassPool programClassPool; + private final GsonRuntimeSettings gsonRuntimeSettings; + private final ClassVisitor instanceCreatorClassVisitor; + private final ClassVisitor typeAdapterClassVisitor; + + /** + * Creates a new GsonBuilderInvocationFinder. + * + * @param programClassPool the program class pool used to look + * up class references. + * @param instanceCreatorClassVisitor visitor to which domain classes for + * which an InstanceCreator is + * registered will be delegated. + * @param typeAdapterClassVisitor visitor to which domain classes for + * which a TypeAdapter is registered + * will be delegated. + */ + public GsonBuilderInvocationFinder(ClassPool programClassPool, + GsonRuntimeSettings gsonRuntimeSettings, + ClassVisitor instanceCreatorClassVisitor, + ClassVisitor typeAdapterClassVisitor) + { + this.programClassPool = programClassPool; + this.gsonRuntimeSettings = gsonRuntimeSettings; + this.instanceCreatorClassVisitor = instanceCreatorClassVisitor; + this.typeAdapterClassVisitor = typeAdapterClassVisitor; + + InstructionSequenceBuilder builder = new InstructionSequenceBuilder(); + + Instruction[] setVersionInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SET_VERSION, + GsonClassConstants.METHOD_TYPE_SET_VERSION) + .instructions(); + + Instruction[] excludeFieldsWithModifiersInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_EXCLUDE_FIELDS_WITH_MODIFIERS, + GsonClassConstants.METHOD_TYPE_EXCLUDE_FIELDS_WITH_MODIFIERS) + .instructions(); + + Instruction[] generateNonExecutableJsonInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_GENERATE_EXECUTABLE_JSON, + GsonClassConstants.METHOD_TYPE_GENERATE_EXECUTABLE_JSON) + .instructions(); + + Instruction[] excludeFieldsWithoutExposeAnnotationInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_EXCLUDE_FIELDS_WITHOUT_EXPOSE_ANNOTATION, + GsonClassConstants.METHOD_TYPE_EXLCUDE_FIELDS_WITHOUT_EXPOSE_ANNOTATION) + .instructions(); + + Instruction[] serializeNullsInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SERIALIZE_NULLS, + GsonClassConstants.METHOD_TYPE_SERIALIZE_NULLS) + .instructions(); + + Instruction[] enableComplexMapKeySerializationInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_ENABLE_COMPLEX_MAP_KEY_SERIALIZATION, + GsonClassConstants.METHOD_TYPE_ENABLE_COMPLEX_MAP_KEY_SERIALIZATION) + .instructions(); + + Instruction[] disableInnerClassSerializationInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_DISABLE_INNER_CLASS_SERIALIZATION, + GsonClassConstants.METHOD_TYPE_DISABLE_INNER_CLASS_SERIALIZATION) + .instructions(); + + Instruction[] setLongSerializationPolicyInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SET_LONG_SERIALIZATION_POLICY, + GsonClassConstants.METHOD_TYPE_SET_LONG_SERIALIZATION_POLICY) + .instructions(); + + Instruction[] setFieldNamingStrategyInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SET_FIELD_NAMING_STRATEGY, + GsonClassConstants.METHOD_TYPE_SET_FIELD_NAMING_STRATEGY) + .instructions(); + + Instruction[] setFieldNamingPolicyInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SET_FIELD_NAMING_POLICY, + GsonClassConstants.METHOD_TYPE_SET_FIELD_NAMING_POLICY) + .instructions(); + + Instruction[] setExclusionStrategiesInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SET_EXCLUSION_STRATEGIES, + GsonClassConstants.METHOD_TYPE_SET_EXCLUSION_STRATEGIES) + .instructions(); + + Instruction[] addSerializationExclusionStrategyInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_ADD_SERIALIZATION_EXCLUSION_STRATEGY, + GsonClassConstants.METHOD_TYPE_ADD_SERIALIZATION_EXCLUSION_STRATEGY) + .instructions(); + + Instruction[] addDeserializationExclusionStrategyInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_ADD_DESERIALIZATION_EXCLUSION_STRATEGY, + GsonClassConstants.METHOD_TYPE_ADD_DESERIALIZATION_EXCLUSION_STRATEGY) + .instructions(); + + Instruction[] registerTypeAdapterInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_REGISTER_TYPE_ADAPTER, + GsonClassConstants.METHOD_TYPE_REGISTER_TYPE_ADAPTER) + .instructions(); + + Instruction[] registerTypeHierarchyAdapterInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_REGISTER_TYPE_HIERARCHY_ADAPTER, + GsonClassConstants.METHOD_TYPE_REGISTER_TYPE_HIERARCHY_ADAPTER) + .instructions(); + + Instruction[] serializeSpecialFloatingPointValuesInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON_BUILDER, + GsonClassConstants.METHOD_NAME_SERIALIZE_SPECIAL_FLOATING_POINT_VALUES, + GsonClassConstants.METHOD_TYPE_SERIALIZE_SPECIAL_FLOATING_POINT_VALUES) + .instructions(); + + Constant[] constants = builder.constants(); + + setVersionMatcher = new InstructionSequenceMatcher(constants, + setVersionInstructions); + + excludeFieldsWithModifiersMatcher = + new InstructionSequenceMatcher(constants, + excludeFieldsWithModifiersInstructions); + + generateNonExecutableJsonMatcher = + new InstructionSequenceMatcher(constants, + generateNonExecutableJsonInstructions); + + excludeFieldsWithoutExposeAnnotationMatcher = + new InstructionSequenceMatcher(constants, + excludeFieldsWithoutExposeAnnotationInstructions); + + serializeNullsMatcher = new InstructionSequenceMatcher(constants, + serializeNullsInstructions); + + disableInnerClassSerializationMatcher = + new InstructionSequenceMatcher(constants, + disableInnerClassSerializationInstructions); + + setLongSerializationPolicyMatcher = + new InstructionSequenceMatcher(constants, + setLongSerializationPolicyInstructions); + + setFieldNamingPolicyMatcher = + new InstructionSequenceMatcher(constants, + setFieldNamingPolicyInstructions); + + setFieldNamingStrategyMatcher = + new InstructionSequenceMatcher(constants, + setFieldNamingStrategyInstructions); + + setExclusionStrategiesMatcher = + new InstructionSequenceMatcher(constants, + setExclusionStrategiesInstructions); + + addSerializationExclusionStrategyMatcher = + new InstructionSequenceMatcher(constants, + addSerializationExclusionStrategyInstructions); + + addDeserializationExclusionStrategyMatcher = + new InstructionSequenceMatcher(constants, + addDeserializationExclusionStrategyInstructions); + + registerTypeAdapterMatcher = + new InstructionSequenceMatcher(constants, + registerTypeAdapterInstructions); + + registerTypeHierachyAdapterMatcher = + new InstructionSequenceMatcher(constants, + registerTypeHierarchyAdapterInstructions); + + serializeSpecialFloatingPointValuesMatcher = + new InstructionSequenceMatcher(constants, + serializeSpecialFloatingPointValuesInstructions); + } + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + if (!gsonRuntimeSettings.setVersion) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + setVersionMatcher); + + gsonRuntimeSettings.setVersion = setVersionMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.excludeFieldsWithModifiers) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + excludeFieldsWithModifiersMatcher); + + gsonRuntimeSettings.excludeFieldsWithModifiers = + excludeFieldsWithModifiersMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.generateNonExecutableJson) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + generateNonExecutableJsonMatcher); + + gsonRuntimeSettings.generateNonExecutableJson = + generateNonExecutableJsonMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.excludeFieldsWithoutExposeAnnotation) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + excludeFieldsWithoutExposeAnnotationMatcher); + + gsonRuntimeSettings.excludeFieldsWithoutExposeAnnotation = + excludeFieldsWithoutExposeAnnotationMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.serializeNulls) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + serializeNullsMatcher); + + gsonRuntimeSettings.serializeNulls = + serializeNullsMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.disableInnerClassSerialization) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + disableInnerClassSerializationMatcher); + + gsonRuntimeSettings.disableInnerClassSerialization = + disableInnerClassSerializationMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.setLongSerializationPolicy) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + setLongSerializationPolicyMatcher); + + gsonRuntimeSettings.setLongSerializationPolicy = + setLongSerializationPolicyMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.setFieldNamingPolicy) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + setFieldNamingPolicyMatcher); + + gsonRuntimeSettings.setFieldNamingPolicy = + setFieldNamingPolicyMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.setFieldNamingStrategy) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + setFieldNamingStrategyMatcher); + + gsonRuntimeSettings.setFieldNamingStrategy = + setFieldNamingStrategyMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.setExclusionStrategies) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + setExclusionStrategiesMatcher); + + gsonRuntimeSettings.setExclusionStrategies = + setExclusionStrategiesMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.addSerializationExclusionStrategy) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + addSerializationExclusionStrategyMatcher); + + gsonRuntimeSettings.addSerializationExclusionStrategy = + addSerializationExclusionStrategyMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.addDeserializationExclusionStrategy) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + addDeserializationExclusionStrategyMatcher); + + gsonRuntimeSettings.addDeserializationExclusionStrategy = + addDeserializationExclusionStrategyMatcher.isMatching(); + } + + if (!gsonRuntimeSettings.serializeSpecialFloatingPointValues) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + serializeSpecialFloatingPointValuesMatcher); + + gsonRuntimeSettings.serializeSpecialFloatingPointValues = + serializeSpecialFloatingPointValuesMatcher.isMatching(); + } + + if (instanceCreatorClassVisitor != null && typeAdapterClassVisitor != null) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + registerTypeAdapterMatcher); + instruction.accept(clazz, + method, + codeAttribute, + offset, + registerTypeHierachyAdapterMatcher); + + if (registerTypeAdapterMatcher.isMatching() || + registerTypeHierachyAdapterMatcher.isMatching()) + { + // Figure out the class for which a type adapter is registered. + lazyPartialEvaluator.visitCodeAttribute(clazz, + method, + codeAttribute); + + // Derive Class from type argument. + InstructionOffsetValue typeProducer = + partialEvaluator.getStackBefore(offset) + .getTopActualProducerValue(1) + .instructionOffsetValue(); + + TypeArgumentFinder typeArgumentFinder = + new TypeArgumentFinder(programClassPool, partialEvaluator); + for (int i = 0; i < typeProducer.instructionOffsetCount(); i++) + { + codeAttribute.instructionAccept(clazz, + method, + typeProducer.instructionOffset(i), + typeArgumentFinder); + } + + if (typeArgumentFinder.typeArgumentClasses != null && + typeArgumentFinder.typeArgumentClasses.length == 1) + { + String typeArgumentClass = + typeArgumentFinder.typeArgumentClasses[0]; + Clazz type = programClassPool.getClass(typeArgumentClass); + + if (type != null) + { + // Derive Class from typeAdapter argument. + InstructionOffsetValue typeAdapterProducer = + partialEvaluator.getStackBefore(offset) + .getTopActualProducerValue(0) + .instructionOffsetValue(); + + TypeArgumentFinder typeAdapterArgumentFinder = + new TypeArgumentFinder(programClassPool, partialEvaluator); + for (int i = 0; i < typeAdapterProducer.instructionOffsetCount(); i++) + { + codeAttribute.instructionAccept(clazz, + method, + typeAdapterProducer.instructionOffset(i), + typeAdapterArgumentFinder); + } + + if (typeAdapterArgumentFinder.typeArgumentClasses != null && + typeAdapterArgumentFinder.typeArgumentClasses.length == 1) + { + // Check whether type adapter passed as argument + // implements InstanceCreator before passing the + // domain type itself to the instanceCreatorClassVisitor. + String typeAdapterArgumentClass = + typeAdapterArgumentFinder.typeArgumentClasses[0]; + Clazz instanceCreator = + programClassPool.getClass(GsonClassConstants.NAME_INSTANCE_CREATOR); + ImplementedClassFilter implementsInstanceCreatorFilter = + new ImplementedClassFilter(instanceCreator, + false, + new ClassVisitorPropagator(type, instanceCreatorClassVisitor), + new ClassVisitorPropagator(type, typeAdapterClassVisitor)); + programClassPool.classAccept(typeAdapterArgumentClass, implementsInstanceCreatorFilter); + } + } + } + } + } + } + + private static class ClassVisitorPropagator + implements ClassVisitor + { + private final Clazz clazz; + private final ClassVisitor classVisitor; + + private ClassVisitorPropagator(Clazz clazz, + ClassVisitor classVisitor) + { + this.clazz = clazz; + this.classVisitor = classVisitor; + } + + // Implementations for ClassVisitor + + @Override + public void visitProgramClass(ProgramClass programClass) + { + clazz.accept(classVisitor); + } + + + @Override + public void visitLibraryClass(LibraryClass libraryClass) {} + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonClassConstants.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonClassConstants.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonClassConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonClassConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,181 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +/** + * Constants used in the classes of the GSON library. + * + * @author Lars Vandenbergh + */ +public class GsonClassConstants +{ + public static final String NAME_GSON_BUILDER = "com/google/gson/GsonBuilder"; + + public static final String METHOD_NAME_ADD_DESERIALIZATION_EXCLUSION_STRATEGY = "addDeserializationExclusionStrategy"; + public static final String METHOD_TYPE_ADD_DESERIALIZATION_EXCLUSION_STRATEGY = "(Lcom/google/gson/ExclusionStrategy;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_ADD_SERIALIZATION_EXCLUSION_STRATEGY = "addSerializationExclusionStrategy"; + public static final String METHOD_TYPE_ADD_SERIALIZATION_EXCLUSION_STRATEGY = "(Lcom/google/gson/ExclusionStrategy;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_DISABLE_INNER_CLASS_SERIALIZATION = "disableInnerClassSerialization"; + public static final String METHOD_TYPE_DISABLE_INNER_CLASS_SERIALIZATION = "()Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_ENABLE_COMPLEX_MAP_KEY_SERIALIZATION = "enableComplexMapKeySerialization"; + public static final String METHOD_TYPE_ENABLE_COMPLEX_MAP_KEY_SERIALIZATION = "()Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_EXCLUDE_FIELDS_WITH_MODIFIERS = "excludeFieldsWithModifiers"; + public static final String METHOD_TYPE_EXCLUDE_FIELDS_WITH_MODIFIERS = "([I)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_EXCLUDE_FIELDS_WITHOUT_EXPOSE_ANNOTATION = "excludeFieldsWithoutExposeAnnotation"; + public static final String METHOD_TYPE_EXLCUDE_FIELDS_WITHOUT_EXPOSE_ANNOTATION = "()Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_GENERATE_EXECUTABLE_JSON = "generateNonExecutableJson"; + public static final String METHOD_TYPE_GENERATE_EXECUTABLE_JSON = "()Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_REGISTER_TYPE_ADAPTER = "registerTypeAdapter"; + public static final String METHOD_TYPE_REGISTER_TYPE_ADAPTER = "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_REGISTER_TYPE_HIERARCHY_ADAPTER = "registerTypeHierarchyAdapter"; + public static final String METHOD_TYPE_REGISTER_TYPE_HIERARCHY_ADAPTER = "(Ljava/lang/Class;Ljava/lang/Object;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SERIALIZE_NULLS = "serializeNulls"; + public static final String METHOD_TYPE_SERIALIZE_NULLS = "()Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SERIALIZE_SPECIAL_FLOATING_POINT_VALUES = "serializeSpecialFloatingPointValues"; + public static final String METHOD_TYPE_SERIALIZE_SPECIAL_FLOATING_POINT_VALUES = "()Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SET_EXCLUSION_STRATEGIES = "setExclusionStrategies"; + public static final String METHOD_TYPE_SET_EXCLUSION_STRATEGIES = "([Lcom/google/gson/ExclusionStrategy;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SET_FIELD_NAMING_POLICY = "setFieldNamingPolicy"; + public static final String METHOD_TYPE_SET_FIELD_NAMING_POLICY = "(Lcom/google/gson/FieldNamingPolicy;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SET_FIELD_NAMING_STRATEGY = "setFieldNamingStrategy"; + public static final String METHOD_TYPE_SET_FIELD_NAMING_STRATEGY = "(Lcom/google/gson/FieldNamingStrategy;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SET_LONG_SERIALIZATION_POLICY = "setLongSerializationPolicy"; + public static final String METHOD_TYPE_SET_LONG_SERIALIZATION_POLICY = "(Lcom/google/gson/LongSerializationPolicy;)Lcom/google/gson/GsonBuilder;"; + public static final String METHOD_NAME_SET_VERSION = "setVersion"; + public static final String METHOD_TYPE_SET_VERSION = "(D)Lcom/google/gson/GsonBuilder;"; + + public static final String NAME_GSON = "com/google/gson/Gson"; + + public static final String FIELD_NAME_EXCLUDER = "excluder"; + public static final String FIELD_TYPE_EXCLUDER = "Lcom/google/gson/internal/Excluder;"; + public static final String FIELD_NAME_FIELD_NAMING_STRATEGY = "fieldNamingStrategy"; + public static final String FIELD_TYPE_FIELD_NAMING_STRATEGY = "Lcom/google/gson/FieldNamingStrategy;"; + public static final String FIELD_NAME_INSTANCE_CREATORS = "instanceCreators"; + public static final String FIELD_TYPE_INSTANCE_CREATORS = "Ljava/util/Map;"; + public static final String FIELD_NAME_TYPE_TOKEN_CACHE = "typeTokenCache"; + public static final String FIELD_TYPE_TYPE_TOKEN_CACHE = "Ljava/util/Map;"; + + public static final String METHOD_NAME_GET_ADAPTER_CLASS = "getAdapter"; + public static final String METHOD_TYPE_GET_ADAPTER_CLASS = "(Ljava/lang/Class;)Lcom/google/gson/TypeAdapter;"; + public static final String METHOD_NAME_GET_ADAPTER_TYPE_TOKEN = "getAdapter"; + public static final String METHOD_TYPE_GET_ADAPTER_TYPE_TOKEN = "(Lcom/google/gson/reflect/TypeToken;)Lcom/google/gson/TypeAdapter;"; + + public static final String METHOD_NAME_TO_JSON = "toJson"; + public static final String METHOD_TYPE_TO_JSON_OBJECT = "(Ljava/lang/Object;)Ljava/lang/String;"; + public static final String METHOD_TYPE_TO_JSON_OBJECT_TYPE = "(Ljava/lang/Object;Ljava/lang/reflect/Type;)Ljava/lang/String;"; + public static final String METHOD_TYPE_TO_JSON_OBJECT_APPENDABLE = "(Ljava/lang/Object;Ljava/lang/Appendable;)V"; + public static final String METHOD_TYPE_TO_JSON_OBJECT_TYPE_APPENDABLE = "(Ljava/lang/Object;Ljava/lang/reflect/Type;Ljava/lang/Appendable;)V"; + public static final String METHOD_TYPE_TO_JSON_OBJECT_TYPE_WRITER = "(Ljava/lang/Object;Ljava/lang/reflect/Type;Lcom/google/gson/stream/JsonWriter;)V"; + public static final String METHOD_TYPE_TO_JSON_JSON_ELEMENT_WRITER = "(Lcom/google/gson/JsonElement;Lcom/google/gson/stream/JsonWriter;)V"; + + public static final String METHOD_NAME_TO_JSON_TREE = "toJsonTree"; + public static final String METHOD_TYPE_TO_JSON_TREE_OBJECT = "(Ljava/lang/Object;)Lcom/google/gson/JsonElement;"; + public static final String METHOD_TYPE_TO_JSON_TREE_OBJECT_TYPE = "(Ljava/lang/Object;Ljava/lang/reflect/Type;)Lcom/google/gson/JsonElement;"; + + public static final String METHOD_NAME_FROM_JSON = "fromJson"; + public static final String METHOD_TYPE_FROM_JSON_STRING_CLASS = "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; + public static final String METHOD_TYPE_FROM_JSON_STRING_TYPE = "(Ljava/lang/String;Ljava/lang/reflect/Type;)Ljava/lang/Object;"; + public static final String METHOD_TYPE_FROM_JSON_READER_CLASS = "(Ljava/io/Reader;Ljava/lang/Class;)Ljava/lang/Object;"; + public static final String METHOD_TYPE_FROM_JSON_READER_TYPE = "(Ljava/io/Reader;Ljava/lang/reflect/Type;)Ljava/lang/Object;"; + public static final String METHOD_TYPE_FROM_JSON_JSON_READER_TYPE = "(Lcom/google/gson/stream/JsonReader;Ljava/lang/reflect/Type;)Ljava/lang/Object;"; + + public static final String NAME_TYPE_TOKEN = "com/google/gson/reflect/TypeToken"; + public static final String METHOD_NAME_GET_TYPE = "getType"; + public static final String METHOD_TYPE_GET_TYPE = "()Ljava/lang/reflect/Type;"; + public static final String METHOD_NAME_GET_RAW_TYPE = "getRawType"; + public static final String METHOD_TYPE_GET_RAW_TYPE = "()Ljava/lang/Class;"; + + public static final String NAME_EXCLUDER = "com/google/gson/internal/Excluder"; + public static final String FIELD_NAME_DESERIALIZATION_STRATEGIES = "deserializationStrategies"; + public static final String FIELD_TYPE_DESERIALIZATION_STRATEGIES = "Ljava/util/List;"; + public static final String FIELD_NAME_MODIFIERS = "modifiers"; + public static final String FIELD_TYPE_MODIFIERS = "I"; + public static final String FIELD_NAME_SERIALIZATION_STRATEGIES = "serializationStrategies"; + public static final String FIELD_TYPE_SERIALIZATION_STRATEGIES = "Ljava/util/List;"; + public static final String FIELD_NAME_VERSION = "version"; + public static final String FIELD_TYPE_VERSION = "D"; + + public static final String NAME_INSTANCE_CREATOR = "com/google/gson/InstanceCreator"; + + public static final String METHOD_NAME_CREATE_INSTANCE = "createInstance"; + public static final String METHOD_TYPE_CREATE_INSTANCE = "(Ljava/lang/reflect/Type;)Ljava/lang/Object;"; + + public static final String NAME_TYPE_ADAPTER = "com/google/gson/TypeAdapter"; + public static final String METHOD_NAME_READ = "read"; + public static final String METHOD_TYPE_READ = "(Lcom/google/gson/stream/JsonReader;)Ljava/lang/Object;"; + public static final String METHOD_NAME_WRITE = "write"; + public static final String METHOD_TYPE_WRITE = "(Lcom/google/gson/stream/JsonWriter;Ljava/lang/Object;)V"; + + public static final String NAME_FIELD_NAMING_POLICY = "com/google/gson/FieldNamingPolicy"; + public static final String FIELD_NAME_IDENTITY = "IDENTITY"; + public static final String FIELD_TYPE_IDENTITY = "Lcom/google/gson/FieldNamingPolicy;"; + + public static final String NAME_JSON_READER = "com/google/gson/stream/JsonReader"; + + public static final String METHOD_NAME_READER_BEGIN_OBJECT = "beginObject"; + public static final String METHOD_TYPE_READER_BEGIN_OBJECT = "()V"; + public static final String METHOD_NAME_READER_END_OBJECT = "endObject"; + public static final String METHOD_TYPE_READER_END_OBJECT = "()V"; + public static final String METHOD_NAME_NEXT_STRING = "nextString"; + public static final String METHOD_TYPE_NEXT_STRING = "()Ljava/lang/String;"; + public static final String METHOD_NAME_NEXT_BOOLEAN = "nextBoolean"; + public static final String METHOD_TYPE_NEXT_BOOLEAN = "()Z"; + public static final String METHOD_NAME_NEXT_INTEGER = "nextInt"; + public static final String METHOD_TYPE_NEXT_INTEGER = "()I"; + public static final String METHOD_NAME_NEXT_NULL = "nextNull"; + public static final String METHOD_TYPE_NEXT_NULL = "()V"; + public static final String METHOD_NAME_SKIP_VALUE = "skipValue"; + public static final String METHOD_TYPE_SKIP_VALUE = "()V"; + + public static final String NAME_JSON_WRITER = "com/google/gson/stream/JsonWriter"; + + public static final String METHOD_NAME_WRITER_BEGIN_OBJECT = "beginObject"; + public static final String METHOD_TYPE_WRITER_BEGIN_OBJECT = "()Lcom/google/gson/stream/JsonWriter;"; + public static final String METHOD_NAME_WRITER_END_OBJECT = "endObject"; + public static final String METHOD_TYPE_WRITER_END_OBJECT = "()Lcom/google/gson/stream/JsonWriter;"; + public static final String METHOD_NAME_HAS_NEXT = "hasNext"; + public static final String METHOD_TYPE_HAS_NEXT = "()Z"; + public static final String METHOD_NAME_PEEK = "peek"; + public static final String METHOD_TYPE_PEEK = "()Lcom/google/gson/stream/JsonToken;"; + public static final String METHOD_NAME_NULL_VALUE = "nullValue"; + public static final String METHOD_TYPE_NULL_VALUE = "()Lcom/google/gson/stream/JsonWriter;"; + public static final String METHOD_NAME_VALUE_BOOLEAN = "value"; + public static final String METHOD_TYPE_VALUE_BOOLEAN = "(Z)Lcom/google/gson/stream/JsonWriter;"; + public static final String METHOD_NAME_VALUE_BOOLEAN_OBJECT = "value"; + public static final String METHOD_TYPE_VALUE_BOOLEAN_OBJECT = "(Ljava/lang/Boolean;)Lcom/google/gson/stream/JsonWriter;"; + public static final String METHOD_NAME_VALUE_NUMBER = "value"; + public static final String METHOD_TYPE_VALUE_NUMBER = "(Ljava/lang/Number;)Lcom/google/gson/stream/JsonWriter;"; + public static final String METHOD_NAME_VALUE_STRING = "value"; + public static final String METHOD_TYPE_NAME_VALUE_STRING = "(Ljava/lang/String;)Lcom/google/gson/stream/JsonWriter;"; + + public static final String NAME_JSON_SYNTAX_EXCEPTION = "com/google/gson/JsonSyntaxException"; + + public static final String NAME_JSON_TOKEN = "com/google/gson/stream/JsonToken"; + + public static final String FIELD_NAME_NULL = "NULL"; + public static final String FIELD_TYPE_NULL = "Lcom/google/gson/stream/JsonToken;"; + public static final String FIELD_NAME_BOOLEAN = "BOOLEAN"; + public static final String FIELD_TYPE_BOOLEAN = "Lcom/google/gson/stream/JsonToken;"; + + public static final String ANNOTATION_TYPE_EXPOSE = "Lcom/google/gson/annotations/Expose;"; + public static final String ANNOTATION_TYPE_JSON_ADAPTER = "Lcom/google/gson/annotations/JsonAdapter;"; + public static final String ANNOTATION_TYPE_SERIALIZED_NAME = "Lcom/google/gson/annotations/SerializedName;"; +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonConstructorPatcher.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonConstructorPatcher.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonConstructorPatcher.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonConstructorPatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,237 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.editor.*; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.MemberVisitor; +import proguard.evaluation.*; +import proguard.evaluation.value.*; +import proguard.optimize.evaluation.PartialEvaluator; + +/** + * Class visitor that patches the constructor of Gson so that the injected + * optimized type adapter factory is registered at the right priority. It + * also exposes the Excluder used by Gson to the outside if needed. + * + * @author Lars Vandenbergh + */ +public class GsonConstructorPatcher +extends SimplifiedVisitor +implements MemberVisitor, + AttributeVisitor, + InstructionVisitor +{ + private static final boolean DEBUG = false; + + private final CodeAttributeEditor codeAttributeEditor; + private final TypedReferenceValueFactory valueFactory = + new TypedReferenceValueFactory(); + private final PartialEvaluator partialEvaluator = + new PartialEvaluator(valueFactory, + new BasicInvocationUnit(new TypedReferenceValueFactory()), + true); + private final AttributeVisitor lazyPartialEvaluator = + new AttributeNameFilter(ClassConstants.ATTR_Code, + new SingleTimeAttributeVisitor( + partialEvaluator)); + private final static int THIS_PARAMETER = 0; + private final static int EXCLUDER_PARAMETER = 1; + private int insertionOffset = -1; + private int typeAdapterListLocal = -1; + private boolean addExcluder; + + + /** + * Constructs a new GsonConstructorPatcher. + * + * @param codeAttributeEditor the code attribute editor for editing the + * code attribute of the Gson constructor. + * @param addExcluder determines whether or not to inject + * code for exposing the Gson excluder. + */ + public GsonConstructorPatcher(CodeAttributeEditor codeAttributeEditor, + boolean addExcluder) + { + this.codeAttributeEditor = codeAttributeEditor; + this.addExcluder = addExcluder; + } + + + // Implementations for MemberVisitor. + + @Override + public void visitAnyMember(Clazz clazz, Member member) {} + + + @Override + public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) + { + // We make the assumption that there is one constructor with a List + // of type adapter factories as one of its arguments. This has been + // the case since Gson version 2.0 from 2011. + String descriptor = programMethod.getDescriptor(programClass); + if (descriptor.contains(ClassConstants.TYPE_JAVA_UTIL_LIST)) + { + if(DEBUG) + { + System.out.println("GsonConstructorPatcher: patching " + + programClass.getName() + " " + + programMethod.getName(programClass) + " " + + descriptor); + } + programMethod.attributesAccept(programClass, this); + } + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + // Search for insertion point and local that contains list of type + // adapter factories. + codeAttribute.instructionsAccept(clazz, method, this); + + if (insertionOffset != -1 && typeAdapterListLocal != -1) + { + // Set up the code attribute editor. + codeAttributeEditor.reset(codeAttribute.u4codeLength); + + // Insert instructions for appending type adapter factory to the list. + InstructionSequenceBuilder ____ = new InstructionSequenceBuilder((ProgramClass)clazz); + ____.new_(ClassConstants.NAME_JAVA_UTIL_ARRAY_LIST) + .dup() + .aload(typeAdapterListLocal) + .invokespecial(ClassConstants.NAME_JAVA_UTIL_ARRAY_LIST, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT_COLLECTION) + .astore(typeAdapterListLocal) + .aload(typeAdapterListLocal) + .new_(OptimizedClassConstants.NAME_OPTIMIZED_TYPE_ADAPTER_FACTORY) + .dup() + .invokespecial(OptimizedClassConstants.NAME_OPTIMIZED_TYPE_ADAPTER_FACTORY, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT) + .invokeinterface(ClassConstants.NAME_JAVA_UTIL_LIST, + ClassConstants.METHOD_NAME_ADD, + ClassConstants.METHOD_TYPE_ADD) + .pop(); + + // Insert instructions for assigning excluder to the artificial excluder field. + if (addExcluder) + { + ____.aload(THIS_PARAMETER) + .aload(EXCLUDER_PARAMETER) + .putfield(GsonClassConstants.NAME_GSON, + OptimizedClassConstants.FIELD_NAME_EXCLUDER, + OptimizedClassConstants.FIELD_TYPE_EXCLUDER); + } + codeAttributeEditor.insertAfterInstruction(insertionOffset, ____.instructions()); + + // Apply the insertion. + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + } + + + // Implementations for InstructionVisitor + + @Override + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) + { + if (instruction.actualOpcode() == InstructionConstants.OP_INVOKEINTERFACE && + typeAdapterListLocal == -1) + { + ConstantInstruction constantInstruction = (ConstantInstruction)instruction; + Constant constant = ((ProgramClass)clazz).constantPool[constantInstruction.constantIndex]; + if (constant instanceof InterfaceMethodrefConstant) + { + InterfaceMethodrefConstant interfaceMethodrefConstant = (InterfaceMethodrefConstant)constant; + if (interfaceMethodrefConstant.getClassName(clazz).equals(ClassConstants.NAME_JAVA_UTIL_LIST) && + interfaceMethodrefConstant.getName(clazz).equals(ClassConstants.METHOD_NAME_ADD_ALL) && + interfaceMethodrefConstant.getType(clazz).equals(ClassConstants.METHOD_TYPE_ADD_ALL)) + { + // We found an invocation to List.add(Object). + // Find out which instructions contributed to the top value + // on the stack and visit them to determine which local is + // passed as argument. + lazyPartialEvaluator.visitCodeAttribute(clazz, + method, + codeAttribute); + TracedStack stackBefore = partialEvaluator.getStackBefore(offset); + InstructionOffsetValue instructionOffsetValue = stackBefore.getTopProducerValue(0).instructionOffsetValue(); + for (int instructionIndex = 0; instructionIndex < instructionOffsetValue.instructionOffsetCount(); instructionIndex++) + { + int instructionOffset = instructionOffsetValue.instructionOffset(instructionIndex); + codeAttribute.instructionAccept(clazz, method, instructionOffset, new LocalFinder()); + } + } + } + } + else if (instruction.actualOpcode() == InstructionConstants.OP_INVOKESPECIAL && + insertionOffset == -1) + { + ConstantInstruction constantInstruction = (ConstantInstruction)instruction; + Constant constant = ((ProgramClass)clazz).constantPool[constantInstruction.constantIndex]; + if (constant instanceof MethodrefConstant) + { + MethodrefConstant methodrefConstant = (MethodrefConstant)constant; + if (methodrefConstant.getClassName(clazz).equals(ClassConstants.NAME_JAVA_LANG_OBJECT) && + methodrefConstant.getName(clazz).equals(ClassConstants.METHOD_NAME_INIT) && + methodrefConstant.getType(clazz).equals(ClassConstants.METHOD_TYPE_INIT)) + { + // We want to insert our patch after the call to Object.. + insertionOffset = offset; + } + } + } + } + + + private class LocalFinder + extends SimplifiedVisitor + implements InstructionVisitor + { + // Implementations for InstructionVisitor + + @Override + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) + { + if (instruction.canonicalOpcode() == InstructionConstants.OP_ALOAD) + { + VariableInstruction variableInstruction = (VariableInstruction)instruction; + typeAdapterListLocal = variableInstruction.variableIndex; + } + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonContext.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonContext.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonContext.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonContext.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.ClassPool; +import proguard.classfile.attribute.visitor.AllAttributeVisitor; +import proguard.classfile.instruction.visitor.*; +import proguard.classfile.util.WarningPrinter; +import proguard.classfile.visitor.*; + +/** + * This class groups all information about how the Gson library is being used + * in a program class pool. + * + * @author Lars Vandenbergh + */ +public class GsonContext +{ + public ClassPool filteredClasses; + public ClassPool gsonDomainClassPool; + public ClassPool instanceCreatorClassPool; + public ClassPool typeAdapterClassPool; + public GsonRuntimeSettings gsonRuntimeSettings; + + + /** + * Sets up the Gson context for the given program class pool. + * Notes will be printed to the given printer if provided. + * + * @param programClassPool the program class pool + * @param notePrinter the optional note printer to which notes + * can be printed. + */ + public void setupFor(ClassPool programClassPool, + WarningPrinter notePrinter) + { + // Only apply remaining optimizations to classes that are not part of + // Gson itself. + filteredClasses = new ClassPool(); + programClassPool.classesAccept( + new ClassNameFilter("!com/google/gson/**", + new ClassPoolFiller(filteredClasses))); + + // Find all GsonBuilder invocations. + gsonRuntimeSettings = new GsonRuntimeSettings(); + instanceCreatorClassPool = new ClassPool(); + typeAdapterClassPool = new ClassPool(); + GsonBuilderInvocationFinder gsonBuilderInvocationFinder = + new GsonBuilderInvocationFinder( + programClassPool, + gsonRuntimeSettings, + new ClassPoolFiller(instanceCreatorClassPool), + new ClassPoolFiller(typeAdapterClassPool)); + + filteredClasses.classesAccept( + new AllMethodVisitor( + new AllAttributeVisitor( + new AllInstructionVisitor(gsonBuilderInvocationFinder)))); + + // Find all Gson invocations. + gsonDomainClassPool = new ClassPool(); + GsonDomainClassFinder domainClassFinder = + new GsonDomainClassFinder(typeAdapterClassPool, + gsonDomainClassPool, + notePrinter); + + filteredClasses.accept( + new AllClassVisitor( + new AllMethodVisitor( + new AllAttributeVisitor( + new AllInstructionVisitor( + new MultiInstructionVisitor( + new GsonSerializationInvocationFinder(programClassPool, + domainClassFinder, + notePrinter), + new GsonDeserializationInvocationFinder(programClassPool, + domainClassFinder, + notePrinter))))))); + } + +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonDeserializationInvocationFinder.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonDeserializationInvocationFinder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonDeserializationInvocationFinder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonDeserializationInvocationFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,236 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.Constant; +import proguard.classfile.editor.InstructionSequenceBuilder; +import proguard.classfile.instruction.Instruction; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.ClassVisitor; +import proguard.evaluation.BasicInvocationUnit; +import proguard.evaluation.value.*; +import proguard.optimize.evaluation.PartialEvaluator; + +/** + * This instruction visitor searches the code for invocations to any of the + * deserialization methods of Gson (all the fromJson variants) and keeps + * track of the domain classes that are involved in the deserialization. + * + * @author Lars Vandenbergh + */ +public class GsonDeserializationInvocationFinder +extends SimplifiedVisitor +implements InstructionVisitor +{ + //* + private static final boolean DEBUG = false; + /*/ + public static boolean DEBUG = System.getProperty("gdif") != null; + //*/ + + private final ClassPool programClassPool; + private final ClassVisitor domainClassVisitor; + private final WarningPrinter notePrinter; + private final FromJsonInvocationMatcher[] fromJsonInvocationMatchers; + private final TypedReferenceValueFactory valueFactory = + new TypedReferenceValueFactory(); + private final PartialEvaluator partialEvaluator = + new PartialEvaluator(valueFactory, + new BasicInvocationUnit(new TypedReferenceValueFactory()), + true); + private final AttributeVisitor lazyPartialEvaluator = + new AttributeNameFilter(ClassConstants.ATTR_Code, + new SingleTimeAttributeVisitor( + partialEvaluator)); + + + /** + * Creates a new GsonDeserializationInvocationFinder. + * + * @param programClassPool the program class pool used to look up class + * references. + * @param domainClassVisitor the visitor to which found domain classes that + * are involved in Gson deserialization will + * be delegated. + * @param notePrinter used to print notes about domain classes that + * can not be handled by the Gson optimization. + */ + public GsonDeserializationInvocationFinder(ClassPool programClassPool, + ClassVisitor domainClassVisitor, + WarningPrinter notePrinter) + { + this.programClassPool = programClassPool; + this.domainClassVisitor = domainClassVisitor; + this.notePrinter = notePrinter; + + // Create matchers for relevant instruction sequences. + InstructionSequenceBuilder builder = new InstructionSequenceBuilder(); + + // The invocation "Gson#fromJson(String, Class)". + Instruction[] fromJsonStringClassInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_FROM_JSON, + GsonClassConstants.METHOD_TYPE_FROM_JSON_STRING_CLASS) + .instructions(); + + // The invocation "Gson#fromJson(String, Type)". + Instruction[] fromJsonStringTypeInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_FROM_JSON, + GsonClassConstants.METHOD_TYPE_FROM_JSON_STRING_TYPE) + .instructions(); + + // The invocation "Gson#fromJson(Reader, Class)". + Instruction[] fromJsonReaderClassInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_FROM_JSON, + GsonClassConstants.METHOD_TYPE_FROM_JSON_READER_CLASS) + .instructions(); + + // The invocation "Gson#fromJson(Reader, Type)". + Instruction[] fromJsonReaderTypeInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_FROM_JSON, + GsonClassConstants.METHOD_TYPE_FROM_JSON_READER_TYPE) + .instructions(); + + // The invocation "Gson#fromJson(JsonReader, Type)". + Instruction[] fromJsonJsonReaderTypeInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_FROM_JSON, + GsonClassConstants.METHOD_TYPE_FROM_JSON_JSON_READER_TYPE) + .instructions(); + + Constant[] constants = builder.constants(); + + fromJsonInvocationMatchers = new FromJsonInvocationMatcher[] + { + new FromJsonInvocationMatcher(constants, fromJsonStringClassInstructions, 0, -1), + new FromJsonInvocationMatcher(constants, fromJsonStringTypeInstructions, -1, 0), + new FromJsonInvocationMatcher(constants, fromJsonReaderClassInstructions, 0, -1), + new FromJsonInvocationMatcher(constants, fromJsonReaderTypeInstructions, -1, 0), + new FromJsonInvocationMatcher(constants, fromJsonJsonReaderTypeInstructions, -1, 0) + }; + } + + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) + { + // Try to match any of the fromJson() constructs. + FromJsonInvocationMatcher matchingMatcher = null; + for (FromJsonInvocationMatcher matcher : fromJsonInvocationMatchers) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + matcher); + if(matcher.isMatching()) + { + matchingMatcher = matcher; + break; + } + } + + if (matchingMatcher != null) + { + if (DEBUG) + { + System.out.println("GsonDeserializationInvocationFinder: Gson#fromJson: " + + clazz.getName() + + "." + + method.getName(clazz) + + method.getDescriptor(clazz) + + " " + + instruction.toString(offset)); + } + + // Figure out the type that is being deserialized. + lazyPartialEvaluator.visitCodeAttribute(clazz, + method, + codeAttribute); + + // Derive types from Class or Type argument. + int stackElementIndex = matchingMatcher.typeStackElementIndex == -1 ? + matchingMatcher.classStackElementIndex : + matchingMatcher.typeStackElementIndex; + InstructionOffsetValue producer = + partialEvaluator.getStackBefore(offset) + .getTopActualProducerValue(stackElementIndex) + .instructionOffsetValue(); + + TypeArgumentFinder typeArgumentFinder = + new TypeArgumentFinder(programClassPool, partialEvaluator); + for (int i = 0; i < producer.instructionOffsetCount(); i++) + { + codeAttribute.instructionAccept(clazz, + method, + producer.instructionOffset(i), + typeArgumentFinder); + } + + String[] targetTypes = typeArgumentFinder.typeArgumentClasses; + if (targetTypes != null) + { + for (String targetType : targetTypes) + { + programClassPool.classAccept(targetType, domainClassVisitor); + } + } + else if (notePrinter != null) + { + notePrinter.print(clazz.getName(), + "Note: can't derive deserialized type from fromJson() invocation in " + + clazz.getName() + + "." + + method.getName(clazz) + + method.getDescriptor(clazz)); + } + } + } + + + // Utility classes. + + private static class FromJsonInvocationMatcher + extends InstructionSequenceMatcher + { + private int classStackElementIndex; + private int typeStackElementIndex; + + private FromJsonInvocationMatcher(Constant[] patternConstants, + Instruction[] patternInstructions, + int classStackElementIndex, + int typeStackElementIndex) + { + super(patternConstants, patternInstructions); + this.classStackElementIndex = classStackElementIndex; + this.typeStackElementIndex = typeStackElementIndex; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonDeserializationOptimizer.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonDeserializationOptimizer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonDeserializationOptimizer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonDeserializationOptimizer.java 2019-10-04 12:07:45.000000000 +0000 @@ -0,0 +1,685 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.editor.CodeAttributeEditor.Label; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.optimize.info.ProgramMemberOptimizationInfoSetter; +import proguard.util.MultiValueMap; + +import java.util.*; + +import static proguard.classfile.ClassConstants.*; +import static proguard.optimize.gson.OptimizedClassConstants.*; + +/** + * This visitor injects a fromJson$xxx() method into the classes that it visits + * that deserializes its fields from Json. + * + * @author Lars Vandenbergh + * @author Rob Coekaerts + */ +public class GsonDeserializationOptimizer +extends SimplifiedVisitor +implements ClassVisitor, + MemberVisitor, + AttributeVisitor +{ + private static final boolean DEBUG = false; + + private static final Map inlineDeserializers = new HashMap(); + + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final GsonRuntimeSettings gsonRuntimeSettings; + private final CodeAttributeEditor codeAttributeEditor; + private final OptimizedJsonInfo deserializationInfo; + private final boolean supportExposeAnnotation; + private final MultiValueMap injectedClassNameMap; + + private InstructionSequenceBuilder ____; + private OptimizedJsonInfo.ClassJsonInfo classDeserializationInfo; + private Map javaToJsonFieldNames; + private Map caseLabelByJavaFieldName; + private CodeAttributeEditor.Label endSwitch; + + static + { + inlineDeserializers.put(ClassConstants.TYPE_BYTE + "", + new InlineDeserializers.InlinePrimitiveIntegerDeserializer(byte.class)); + inlineDeserializers.put(ClassConstants.TYPE_SHORT + "", + new InlineDeserializers.InlinePrimitiveIntegerDeserializer(short.class)); + inlineDeserializers.put(ClassConstants.TYPE_INT + "", + new InlineDeserializers.InlinePrimitiveIntegerDeserializer()); + inlineDeserializers.put(ClassConstants.TYPE_JAVA_LANG_STRING, + new InlineDeserializers.InlineStringDeserializer()); + } + + + /** + * Creates a new GsonDeserializationOptimizer. + * + * @param programClassPool the program class pool to initialize added + * references. + * @param libraryClassPool the library class pool to initialize added + * references. + * @param gsonRuntimeSettings keeps track of all GsonBuilder invocations. + * @param codeAttributeEditor the code editor that is be used to inject + * optimized code into the domain classes. + * @param deserializationInfo contains information on which class and + * fields need to be optimized and how. + * @param injectedClassNameMap the map that keeps track of injected + * classes. + */ + public GsonDeserializationOptimizer(ClassPool programClassPool, + ClassPool libraryClassPool, + GsonRuntimeSettings gsonRuntimeSettings, + CodeAttributeEditor codeAttributeEditor, + OptimizedJsonInfo deserializationInfo, + MultiValueMap injectedClassNameMap) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.gsonRuntimeSettings = gsonRuntimeSettings; + this.codeAttributeEditor = codeAttributeEditor; + this.deserializationInfo = deserializationInfo; + this.supportExposeAnnotation = gsonRuntimeSettings.excludeFieldsWithoutExposeAnnotation; + this.injectedClassNameMap = injectedClassNameMap; + } + + + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) {} + + + public void visitProgramClass(ProgramClass programClass) + { + // Make access public for _OptimizedTypeAdapterFactory and _OptimizedTypeAdapterImpl. + programClass.u2accessFlags &= ~ClassConstants.ACC_PRIVATE; + programClass.u2accessFlags |= ClassConstants.ACC_PUBLIC; + + // Make default constructor public for _OptimizedTypeAdapterImpl. + MemberCounter constructorCounter = new MemberCounter(); + programClass.methodsAccept( + new MemberNameFilter(ClassConstants.METHOD_NAME_INIT, + new MemberDescriptorFilter(ClassConstants.METHOD_TYPE_INIT, + new MultiMemberVisitor( + new MemberAccessSetter(ClassConstants.ACC_PUBLIC), + constructorCounter)))); + + // Start adding new deserialization methods. + SimplifiedClassEditor classEditor = + new SimplifiedClassEditor(programClass); + ____ = new InstructionSequenceBuilder(programClass, + programClassPool, + libraryClassPool); + + if (constructorCounter.getCount() == 0) + { + addDefaultConstructor(programClass, + classEditor); + } + + int classIndex = deserializationInfo.classIndices.get(programClass.getName()); + + addFromJsonMethod(programClass, + classEditor, + classIndex); + + addFromJsonFieldMethod(programClass, + classEditor, + classIndex); + + // Update all references of the edited class. + programClass.accept(new MethodLinker()); + classEditor.finishEditing(programClassPool, + libraryClassPool); + } + + private void addDefaultConstructor(ProgramClass programClass, + SimplifiedClassEditor classEditor) + { + if (DEBUG) + { + System.out.println( + "GsonDeserializationOptimizer: adding default constructor to " + + programClass.getName()); + } + + classEditor.addMethod( + ClassConstants.ACC_PUBLIC | + ClassConstants.ACC_SYNTHETIC, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT, + ____.aload_0() // this + .invokespecial(programClass.getSuperName(), + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT) + .return_() + .instructions() + ).accept(programClass, new ProgramMemberOptimizationInfoSetter()); + } + + + private void addFromJsonMethod(ProgramClass programClass, + SimplifiedClassEditor classEditor, + int classIndex) + { + String methodNameFromJson = METHOD_NAME_FROM_JSON + classIndex; + + if (DEBUG) + { + System.out.println( + "GsonDeserializationOptimizer: adding " + + methodNameFromJson + + " method to " + programClass.getName()); + } + + ProgramMethod fromJsonMethod = classEditor.addMethod( + ClassConstants.ACC_PUBLIC | ClassConstants.ACC_SYNTHETIC, + methodNameFromJson, + OptimizedClassConstants.METHOD_TYPE_FROM_JSON, + ____.return_() + .instructions()); + + fromJsonMethod.accept(programClass, + new ProgramMemberOptimizationInfoSetter()); + + // Edit code attribute of fromJson$. + fromJsonMethod.attributesAccept(programClass, + new FromJsonCodeAttributeVisitor()); + } + + + private class FromJsonCodeAttributeVisitor + extends SimplifiedVisitor + implements AttributeVisitor + { + + // Implementations for AttributeVisitor. + + + @Override + public void visitCodeAttribute(Clazz clazz, + Method method, + CodeAttribute codeAttribute) + { + // Create new CodeAttributeEditor for the fromJson$ method. + codeAttributeEditor.reset(1); + + // Begin Json object. + ____.aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_READER_BEGIN_OBJECT, + GsonClassConstants.METHOD_TYPE_READER_BEGIN_OBJECT); + + // Assign locals for nextFieldIndex. + int nextFieldIndexLocalIndex = codeAttribute.u2maxLocals; + + // Start while loop that iterates over Json fields. + CodeAttributeEditor.Label startWhile = codeAttributeEditor.label(); + CodeAttributeEditor.Label endJsonObject = codeAttributeEditor.label(); + + // Is there a next field? If not, terminate loop and end object. + ____.label(startWhile) + .aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_HAS_NEXT, + GsonClassConstants.METHOD_TYPE_HAS_NEXT) + .ifeq(endJsonObject.offset()); + + // Get next field index and store it in a local. + ____.aload(FromJsonLocals.OPTIMIZED_JSON_READER) + .aload(FromJsonLocals.JSON_READER) + .invokeinterface(OptimizedClassConstants.NAME_OPTIMIZED_JSON_READER, + OptimizedClassConstants.METHOD_NAME_NEXT_FIELD_INDEX, + OptimizedClassConstants.METHOD_TYPE_NEXT_FIELD_INDEX) + .istore(nextFieldIndexLocalIndex); + + // Invoke fromJsonField$ with the stored field index. + classDeserializationInfo = deserializationInfo.classJsonInfos.get(clazz.getName()); + javaToJsonFieldNames = classDeserializationInfo.javaToJsonFieldNames; + Integer classIndex = deserializationInfo.classIndices.get(clazz.getName()); + + String methodNameFromJsonField = METHOD_NAME_FROM_JSON_FIELD + classIndex; + ____.aload(FromJsonLocals.THIS) + .aload(FromJsonLocals.GSON) + .aload(FromJsonLocals.JSON_READER) + .iload(nextFieldIndexLocalIndex) + .invokevirtual(clazz.getName(), + + methodNameFromJsonField, + METHOD_TYPE_FROM_JSON_FIELD); + + // Jump to start of while loop. + ____.goto_(startWhile.offset()); + + // End Json object. + ____.label(endJsonObject) + .aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_READER_END_OBJECT, + GsonClassConstants.METHOD_TYPE_READER_END_OBJECT) + .return_(); + + // Add all fromJson$ instructions. + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + } + + + private void addFromJsonFieldMethod(ProgramClass programClass, + SimplifiedClassEditor classEditor, + int classIndex) + { + String methodNameFromJsonField = METHOD_NAME_FROM_JSON_FIELD + classIndex; + + if (DEBUG) + { + System.out.println( + "GsonDeserializationOptimizer: adding " + + methodNameFromJsonField + + " method to " + programClass.getName()); + } + + ProgramMethod fromJsonFieldMethod = classEditor.addMethod( + ClassConstants.ACC_PROTECTED | ClassConstants.ACC_SYNTHETIC, + methodNameFromJsonField, + METHOD_TYPE_FROM_JSON_FIELD, + ____.return_() + .instructions()); + + fromJsonFieldMethod.accept(programClass, + new ProgramMemberOptimizationInfoSetter()); + + // Edit code attribute of fromJsonField$. + fromJsonFieldMethod.attributesAccept(programClass, + new FromJsonFieldCodeAttributeVisitor(supportExposeAnnotation)); + } + + + private class FromJsonFieldCodeAttributeVisitor + extends SimplifiedVisitor + implements AttributeVisitor, + MemberVisitor + { + private int isNullLocalIndex; + private boolean supportExposeAnnotation; + + FromJsonFieldCodeAttributeVisitor(boolean supportExposeAnnotation) + { + this.supportExposeAnnotation = supportExposeAnnotation; + } + + @Override + public void visitCodeAttribute(Clazz clazz, + Method method, + CodeAttribute codeAttribute) + { + // Create new CodeAttributeEditor for the fromJsonField$ method. + codeAttributeEditor.reset(1); + endSwitch = codeAttributeEditor.label(); + + // Are there any fields to be deserialized at the level of this class? + if (javaToJsonFieldNames.size() > 0) + { + // Check for NULL token and store result in boolean local variable. + CodeAttributeEditor.Label tokenNotNull = codeAttributeEditor.label(); + CodeAttributeEditor.Label assignIsNull = codeAttributeEditor.label(); + + isNullLocalIndex = codeAttribute.u2maxLocals; + ____.aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_PEEK, + GsonClassConstants.METHOD_TYPE_PEEK) + .getstatic(GsonClassConstants.NAME_JSON_TOKEN, + GsonClassConstants.FIELD_NAME_NULL, + GsonClassConstants.FIELD_TYPE_NULL); + + ____.ifacmpeq(tokenNotNull.offset()) + .iconst_1() + .goto_(assignIsNull.offset()) + .label(tokenNotNull) + .iconst_0() + .label(assignIsNull) + .istore(isNullLocalIndex); + + generateSwitchTables(clazz); + } + + // If no known field index was returned for this class and + // field, delegate to super method if it exists or skip the value. + if (!clazz.getSuperClass().getName().equals(ClassConstants.NAME_JAVA_LANG_OBJECT)) + { + // Call the superclass fromJsonField$. + Integer superClassIndex = + deserializationInfo.classIndices.get(clazz.getSuperClass().getName()); + String superMethodNameFromJsonField = + METHOD_NAME_FROM_JSON_FIELD + superClassIndex; + + ____.aload(FromJsonFieldLocals.THIS) + .aload(FromJsonFieldLocals.GSON) + .aload(FromJsonFieldLocals.JSON_READER) + .iload(FromJsonFieldLocals.FIELD_INDEX) + .invokevirtual(clazz.getSuperClass().getName(), + superMethodNameFromJsonField, + METHOD_TYPE_FROM_JSON_FIELD); + } + else + { + // Skip field in default case of switch or when no switch is generated. + ____.aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_SKIP_VALUE, + GsonClassConstants.METHOD_TYPE_SKIP_VALUE); + } + + // End of switch. + ____.label(endSwitch) + .return_(); + + // Add all fromJsonField$ instructions. + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + + + private void generateSwitchTables(Clazz clazz) + { + Set exposedJavaFieldNames = classDeserializationInfo.exposedJavaFieldNames; + + Set exposedOrAllJavaFieldNames = supportExposeAnnotation ? exposedJavaFieldNames : + javaToJsonFieldNames.keySet(); + + generateSwitchTable(clazz, + javaToJsonFieldNames, + exposedOrAllJavaFieldNames); + + if (supportExposeAnnotation) + { + // Runtime check whether excludeFieldsWithoutExposeAnnotation is enabled. + // If so, skip this switch statement. + Label nonExposedCasesEnd = codeAttributeEditor.label(); + ____.aload(ToJsonLocals.GSON) + .getfield(GsonClassConstants.NAME_GSON, FIELD_NAME_EXCLUDER, FIELD_TYPE_EXCLUDER) + .getfield(GsonClassConstants.NAME_EXCLUDER, FIELD_NAME_REQUIRE_EXPOSE, FIELD_TYPE_REQUIRE_EXPOSE) + .ifne(nonExposedCasesEnd.offset()); + + Set nonExposedJavaFieldNames = new HashSet(); + for (String javaFieldName: javaToJsonFieldNames.keySet()) + { + if (!exposedJavaFieldNames.contains(javaFieldName)) + { + nonExposedJavaFieldNames.add((javaFieldName)); + } + } + generateSwitchTable(clazz, + javaToJsonFieldNames, + nonExposedJavaFieldNames); + + ____.label(nonExposedCasesEnd); + } + } + + private void generateSwitchTable(Clazz clazz, + Map javaToJsonFieldNames, + Set javaFieldNamesToProcess) + { + ArrayList fromJsonFieldCases = new ArrayList(); + for (Map.Entry javaToJsonFieldNameEntry : javaToJsonFieldNames.entrySet()) + { + if (javaFieldNamesToProcess.contains(javaToJsonFieldNameEntry.getKey())) + { + // Add cases for the alternative Json names with the same label. + String[] jsonFieldNames = javaToJsonFieldNameEntry.getValue(); + Label caseLabel = codeAttributeEditor.label(); + for (String jsonFieldName : jsonFieldNames) + { + fromJsonFieldCases.add(new FromJsonFieldCase(javaToJsonFieldNameEntry.getKey(), + caseLabel, + deserializationInfo.jsonFieldIndices.get(jsonFieldName))); + } + } + } + Collections.sort(fromJsonFieldCases); + + int[] cases = new int[fromJsonFieldCases.size()]; + int[] jumpOffsets = new int[fromJsonFieldCases.size()]; + caseLabelByJavaFieldName = new HashMap(); + for (int caseIndex = 0; caseIndex < fromJsonFieldCases.size(); caseIndex++) + { + FromJsonFieldCase fromJsonFieldCase = fromJsonFieldCases.get(caseIndex); + cases[caseIndex] = fromJsonFieldCase.fieldIndex; + jumpOffsets[caseIndex] = fromJsonFieldCase.label.offset(); + caseLabelByJavaFieldName.put(fromJsonFieldCase.javaFieldName, fromJsonFieldCase.label); + } + + Label defaultCase = codeAttributeEditor.label(); + ____.iload(FromJsonFieldLocals.FIELD_INDEX) + .lookupswitch(defaultCase.offset(), + cases, + jumpOffsets); + + // Apply non static member visitor to all fields to visit. + clazz.fieldsAccept(new MemberAccessFilter(0, + ClassConstants.ACC_SYNTHETIC | + ClassConstants.ACC_STATIC, + this)); + ____.label(defaultCase); + } + + // Implementations for MemberVisitor. + + @Override + public void visitProgramField(ProgramClass programClass, + ProgramField programField) + { + Label fromJsonFieldCaseLabel = caseLabelByJavaFieldName.get(programField.getName(programClass)); + if (fromJsonFieldCaseLabel != null) + { + // Make sure the field is not final anymore so we can safely write it from the injected method. + programField.accept(programClass, new MemberAccessFlagCleaner(ClassConstants.ACC_FINAL)); + + // Check if value is null + CodeAttributeEditor.Label isNull = codeAttributeEditor.label(); + ____.label(fromJsonFieldCaseLabel) + .iload(isNullLocalIndex) + .ifeq(isNull.offset()); + + String fieldDescriptor = programField.getDescriptor(programClass); + FieldSignatureCollector signatureAttributeCollector = new FieldSignatureCollector(); + programField.attributesAccept(programClass, signatureAttributeCollector); + + InlineDeserializer inlineDeserializer = inlineDeserializers.get(fieldDescriptor); + if (inlineDeserializer != null && + inlineDeserializer.canDeserialize(gsonRuntimeSettings)) + { + inlineDeserializer.deserialize(programClass, + programField, + codeAttributeEditor, + ____, + gsonRuntimeSettings); + } + else + { + // Derive the field class and type name for which we want to retrieve the type adapter from Gson. + String fieldTypeName; + String fieldClassName; + if (ClassUtil.isInternalPrimitiveType(fieldDescriptor)) + { + fieldClassName = ClassUtil.internalNumericClassNameFromPrimitiveType(fieldDescriptor.charAt(0)); + fieldTypeName = fieldClassName; + } + else + { + fieldClassName = ClassUtil.internalClassNameFromClassType(fieldDescriptor); + fieldTypeName = fieldDescriptor; + } + + // Derive type token class name if there is a field signature. + String typeTokenClassName = null; + if (signatureAttributeCollector.getFieldSignature() != null) + { + // Add type token sub-class that has the appropriate type parameter. + ProgramClass typeTokenClass = + new TypeTokenClassBuilder(programClass, + programField, + signatureAttributeCollector.getFieldSignature()) + .build(programClassPool); + programClassPool.addClass(typeTokenClass); + typeTokenClass.accept(new ClassReferenceInitializer(programClassPool, + libraryClassPool)); + typeTokenClassName = typeTokenClass.getName(); + injectedClassNameMap.put(programClass.getName(), typeTokenClassName); + } + + // Retrieve type adapter and deserialize value from Json. + if (typeTokenClassName == null) + { + ____.aload(FromJsonLocals.THIS) + .aload(FromJsonLocals.GSON) + .ldc(fieldTypeName, programClassPool.getClass(fieldClassName)) + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_GET_ADAPTER_CLASS, + GsonClassConstants.METHOD_TYPE_GET_ADAPTER_CLASS); + } + else + { + ____.aload(FromJsonLocals.THIS) + .aload(FromJsonLocals.GSON) + .new_(typeTokenClassName) + .dup() + .invokespecial(typeTokenClassName, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT) + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_GET_ADAPTER_TYPE_TOKEN, + GsonClassConstants.METHOD_TYPE_GET_ADAPTER_TYPE_TOKEN); + } + + ____.aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_TYPE_ADAPTER, + GsonClassConstants.METHOD_NAME_READ, + GsonClassConstants.METHOD_TYPE_READ) + .checkcast(fieldTypeName, programClassPool.getClass(fieldClassName)); + + // If the field is primitive, unbox the value before assigning it. + switch (fieldDescriptor.charAt(0)) + { + case ClassConstants.TYPE_BOOLEAN: + ____.invokevirtual(NAME_JAVA_LANG_BOOLEAN, + METHOD_NAME_BOOLEAN_VALUE, + METHOD_TYPE_BOOLEAN_VALUE); + break; + case ClassConstants.TYPE_BYTE: + ____.invokevirtual(NAME_JAVA_LANG_BYTE, + METHOD_NAME_BYTE_VALUE, + METHOD_TYPE_BYTE_VALUE); + break; + case ClassConstants.TYPE_CHAR: + ____.invokevirtual(NAME_JAVA_LANG_CHARACTER, + METHOD_NAME_CHAR_VALUE, + METHOD_TYPE_CHAR_VALUE); + break; + case ClassConstants.TYPE_SHORT: + ____.invokevirtual(NAME_JAVA_LANG_SHORT, + METHOD_NAME_SHORT_VALUE, + METHOD_TYPE_SHORT_VALUE); + break; + case ClassConstants.TYPE_INT: + ____.invokevirtual(NAME_JAVA_LANG_INTEGER, + METHOD_NAME_INT_VALUE, + METHOD_TYPE_INT_VALUE); + break; + case ClassConstants.TYPE_LONG: + ____.invokevirtual(NAME_JAVA_LANG_LONG, + METHOD_NAME_LONG_VALUE, + METHOD_TYPE_LONG_VALUE); + break; + case ClassConstants.TYPE_FLOAT: + ____.invokevirtual(NAME_JAVA_LANG_FLOAT, + METHOD_NAME_FLOAT_VALUE, + METHOD_TYPE_FLOAT_VALUE); + break; + case ClassConstants.TYPE_DOUBLE: + ____.invokevirtual(NAME_JAVA_LANG_DOUBLE, + METHOD_NAME_DOUBLE_VALUE, + METHOD_TYPE_DOUBLE_VALUE); + break; + } + + // Assign deserialized value to field. + ____.putfield(programClass, programField); + } + + // Jump to the end of the switch. + ____.goto_(endSwitch.offset()); + + // Either skip the null (in case of a primitive) or assign the null + // (in case of an object) and jump to the end of the switch. + ____.label(isNull); + + // Why is it necessary to specifically assign a null value? + if (!ClassUtil.isInternalPrimitiveType(fieldDescriptor)) + { + ____.aload(FromJsonLocals.THIS) + .aconst_null() + .putfield(programClass, programField); + } + ____.aload(FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_NEXT_NULL, + GsonClassConstants.METHOD_TYPE_NEXT_NULL) + .goto_(endSwitch.offset()); + } + } + } + + + public static class FromJsonFieldCase implements Comparable + { + private String javaFieldName; + private Label label; + private int fieldIndex; + + public FromJsonFieldCase(String javaFieldName, + Label label, + int fieldIndex) + { + this.javaFieldName = javaFieldName; + this.label = label; + this.fieldIndex = fieldIndex; + } + + @Override + public int compareTo(FromJsonFieldCase fromJsonFieldCase) + { + return this.fieldIndex - fromJsonFieldCase.fieldIndex; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonDomainClassFinder.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonDomainClassFinder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonDomainClassFinder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonDomainClassFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,273 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.annotation.Annotation; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.visitor.AllAttributeVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; + +import java.util.Arrays; + +/** + * This class visitor determines whether a given domain class can be optimized + * by the GSON optimizations and traverses both the class and field hierarchy + * to look for further domain classes. + * + * @author Lars Vandenbergh + */ +public class GsonDomainClassFinder +extends SimplifiedVisitor +implements ClassVisitor +{ + private static final boolean DEBUG = false; + + private final ClassPool typeAdapterClassPool; + private final ClassPool gsonDomainClassPool; + private final WarningPrinter notePrinter; + private final LocalOrAnonymousClassChecker localOrAnonymousClassChecker = + new LocalOrAnonymousClassChecker(); + private final TypeParameterClassChecker typeParameterClassChecker = + new TypeParameterClassChecker(); + private final DuplicateJsonFieldNameChecker duplicateFieldNameChecker = + new DuplicateJsonFieldNameChecker(); + + + /** + * Creates a new GsonDomainClassFinder. + * + * @param typeAdapterClassPool the class pool containing the classes for + * which a custom Gson type adapter is + * registered. + * @param gsonDomainClassPool the class pool to which the found domain + * classes are added. + * @param notePrinter used to print notes about domain classes that + * can not be handled by the Gson optimization. + */ + public GsonDomainClassFinder(ClassPool typeAdapterClassPool, + ClassPool gsonDomainClassPool, + WarningPrinter notePrinter) + { + this.typeAdapterClassPool = typeAdapterClassPool; + this.gsonDomainClassPool = gsonDomainClassPool; + this.notePrinter = notePrinter; + } + + + // Implementations for ClassVisitor. + + @Override + public void visitProgramClass(ProgramClass programClass) + { + if (gsonDomainClassPool.getClass(programClass.getName()) == null) + { + // Local or anonymous classes are excluded by GSON. + programClass.accept(localOrAnonymousClassChecker); + if (localOrAnonymousClassChecker.isLocalOrAnonymous()) + { + // No need to note here because this is not handled + // by GSON either. + return; + } + + if(librarySuperClassCount(programClass) != 0) + { + note(programClass.getName(), + "Note: " + ClassUtil.externalClassName(programClass.getName() + + " can not be optimized for GSON because" + + " it is or inherits from a library class.")); + return; + } + + if(gsonSuperClassCount(programClass) != 0) + { + note(programClass.getName(), + "Note: " + ClassUtil.externalClassName(programClass.getName() + + " can not be optimized for GSON because" + + " it is or inherits from a GSON API class.")); + return; + } + + // Classes with fields that have generic type parameters are + // not supported by our optimization as it is rather complex + // to derive all possible type arguments and generate methods + // for each case. + typeParameterClassChecker.hasFieldWithTypeParameter = false; + programClass.hierarchyAccept(true, + true, + false, + false, + typeParameterClassChecker); + if (typeParameterClassChecker.hasFieldWithTypeParameter) + { + note(programClass.getName(), + "Note: " + ClassUtil.externalClassName(programClass.getName() + + " can not be optimized for GSON because" + + " it uses generic type variables.")); + return; + } + + // Class with duplicate field names are not supported by + // GSON either. + duplicateFieldNameChecker.hasDuplicateJsonFieldNames = false; + programClass.hierarchyAccept(true, + true, + false, + false, + duplicateFieldNameChecker); + if (duplicateFieldNameChecker.hasDuplicateJsonFieldNames) + { + note(programClass.getName(), + "Note: " + ClassUtil.externalClassName(programClass.getName() + + " can not be optimized for GSON because" + + " it contains duplicate field names in its JSON representation.")); + return; + } + + // Classes for which type adapters were registered are not optimized. + ClassCounter typeAdapterClassCounter = new ClassCounter(); + programClass.hierarchyAccept(true, + true, + false, + false, + new ClassPresenceFilter(typeAdapterClassPool, + typeAdapterClassCounter, null)); + if (typeAdapterClassCounter.getCount() > 0) + { + note(programClass.getName(), + "Note: " + ClassUtil.externalClassName(programClass.getName() + + " can not be optimized for GSON because" + + " a custom type adapter is registered for it.")); + return; + } + + // Classes that contain any JsonAdapter annotations are not optimized. + AnnotationFinder annotationFinder = new AnnotationFinder(); + programClass.hierarchyAccept(true, + true, + false, + false, + new MultiClassVisitor( + new AllAttributeVisitor(true, + new AllAnnotationVisitor( + new AnnotationTypeFilter(GsonClassConstants.ANNOTATION_TYPE_JSON_ADAPTER, + annotationFinder))))); + if (annotationFinder.found) + { + note(programClass.getName(), + "Note: " + ClassUtil.externalClassName(programClass.getName() + + " can not be optimized for GSON because" + + " it contains a JsonAdapter annotation.")); + return; + } + + if ((programClass.getAccessFlags() & ClassConstants.ACC_INTERFACE) == 0) + { + if (DEBUG) + { + System.out.println("GsonDomainClassFinder: adding domain class " + + programClass.getName()); + } + + // Add type occurring in toJson() invocation to domain class pool. + gsonDomainClassPool.addClass(programClass); + + // Recursively visit the fields of the domain class and consider + // their classes as domain classes too. + programClass.fieldsAccept( + new MemberAccessFilter(0, ClassConstants.ACC_SYNTHETIC, + new MultiMemberVisitor( + new MemberDescriptorReferencedClassVisitor(this), + new AllAttributeVisitor( + new SignatureAttributeReferencedClassVisitor(this))))); + } + + // Consider super and sub classes as domain classes too. + programClass.hierarchyAccept(false, + true, + false, + true, + this); + } + } + + @Override + public void visitLibraryClass(LibraryClass libraryClass) + { + // Library classes can not be optimized. + } + + + // Utility methods. + + private int librarySuperClassCount(ProgramClass programClass) + { + ClassCounter nonObjectLibrarySuperClassCounter = new ClassCounter(); + programClass.hierarchyAccept(true, + true, + false, + false, + new LibraryClassFilter( + new ClassNameFilter(Arrays.asList("!java/lang/Object", "!java/lang/Enum"), + nonObjectLibrarySuperClassCounter))); + return nonObjectLibrarySuperClassCounter.getCount(); + } + + private int gsonSuperClassCount(ProgramClass programClass) + { + ClassCounter gsonSuperClassCounter = new ClassCounter(); + programClass.hierarchyAccept(true, + true, + false, + false, + new ProgramClassFilter( + new ClassNameFilter("com/google/gson/**", + gsonSuperClassCounter))); + return gsonSuperClassCounter.getCount(); + } + + + private void note(String className, String note) + { + if (notePrinter != null) + { + notePrinter.print(className, note); + notePrinter.print(className, " You should consider keeping this class and its fields."); + } + } + + + private class AnnotationFinder + extends SimplifiedVisitor + implements AnnotationVisitor + { + private boolean found; + + @Override + public void visitAnnotation(Clazz clazz, Annotation annotation) + { + found = true; + } + } + +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonInstrumentationAdder.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonInstrumentationAdder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonInstrumentationAdder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonInstrumentationAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.editor.*; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; + +import static proguard.classfile.instruction.InstructionConstants.OP_ARETURN; +import static proguard.classfile.instruction.InstructionConstants.OP_RETURN; + +/** + * Instruction visitor that adds some instrumentation code to the Gson.toJson() + * and Gson.fromJson() methods that prints out the type adapter cache. This + * can be useful for debugging purposes. + * + * @author Lars Vandenbergh + */ +public class GsonInstrumentationAdder +extends SimplifiedVisitor +implements InstructionVisitor +{ + private static final boolean DEBUG = false; + + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final CodeAttributeEditor codeAttributeEditor; + + + /** + * Creates a new GsonInstrumentationAdder. + * + * @param programClassPool the program class pool used for looking up + * program class references. + * @param libraryClassPool the library class pool used for looking up + * library class references. + * @param codeAttributeEditor the code attribute editor used for editing + * the code attribute of the Gson methods. + */ + public GsonInstrumentationAdder(ClassPool programClassPool, + ClassPool libraryClassPool, + CodeAttributeEditor codeAttributeEditor) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.codeAttributeEditor = codeAttributeEditor; + } + + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + if (instruction.actualOpcode() == OP_RETURN || + instruction.actualOpcode() == OP_ARETURN) + { + String fullyQualifiedMethodName = clazz.getName() + "#" + + method.getName(clazz) + method.getDescriptor(clazz); + if (DEBUG) + { + System.out.println("GsonInstrumentationAdder: instrumenting " + + fullyQualifiedMethodName); + } + + InstructionSequenceBuilder ____ = new InstructionSequenceBuilder((ProgramClass)clazz, + programClassPool, + libraryClassPool); + ____.ldc("Type token cache after invoking " + fullyQualifiedMethodName + ":") + .aload_0() + .getfield(clazz.getName(), + GsonClassConstants.FIELD_NAME_TYPE_TOKEN_CACHE, + GsonClassConstants.FIELD_TYPE_TYPE_TOKEN_CACHE) + .invokestatic(OptimizedClassConstants.NAME_GSON_UTIL, + OptimizedClassConstants.METHOD_NAME_DUMP_TYPE_TOKEN_CACHE, + OptimizedClassConstants.METHOD_TYPE_DUMP_TYPE_TOKEN_CACHE); + + codeAttributeEditor.insertBeforeInstruction(offset, ____.instructions()); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonOptimizer.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonOptimizer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonOptimizer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonOptimizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,320 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.Configuration; +import proguard.classfile.*; +import proguard.classfile.attribute.visitor.AllAttributeVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.io.*; +import proguard.optimize.peephole.*; +import proguard.util.*; + +import java.io.*; +import java.util.*; + +import static proguard.classfile.ClassConstants.ACC_ENUM; +import static proguard.classfile.ClassConstants.CLASS_FILE_EXTENSION; +import static proguard.optimize.gson.GsonClassConstants.NAME_EXCLUDER; +import static proguard.optimize.gson.GsonClassConstants.NAME_GSON; +import static proguard.optimize.gson.OptimizedClassConstants.*; + +/** + * This is the entry point for the GSON optimizations. + * + * The optimization roughly performs the following steps: + * + * - Find all usages of GSON in the program code: calls to toJson() or fromJson(). + * + * - Derive the domain classes that are involved in the GSON call, either + * directly (passed as argument to GSON) or indirectly (a field or element + * type of another domain class). + * + * - Inject optimized methods into the domain classes that serialize and + * deserialize the fields of the domain class without relying on reflection. + * + * - Inject and register GSON type adapters that utilize the optimized + * serialization and deserialization methods on the domain classes and bypass + * the reflective GSON implementation. + * + * As an additional protection measure, the JSON field names are assigned to + * a field index. The mapping between field indices and field names is done + * from the classes _OptimizedJsonReaderImpl and _OptimizedJsonWriterImpl, which + * have String encryption applied to them. This allows injecting serialization + * and deserialization code into the domain classes that have no JSON field + * names stored in them as plain text. + * + * @author Lars Vandenbergh + * @author Rob Coekaerts + */ +public class GsonOptimizer +{ + private static final boolean DEBUG = false; + + // The order of this matters to ensure that the class references are + // initialized properly. + private static final String[] TEMPLATE_CLASSES = + { + NAME_OPTIMIZED_TYPE_ADAPTER, + NAME_GSON_UTIL, + NAME_OPTIMIZED_JSON_READER, + NAME_OPTIMIZED_JSON_READER_IMPL, + NAME_OPTIMIZED_JSON_WRITER, + NAME_OPTIMIZED_JSON_WRITER_IMPL, + NAME_OPTIMIZED_TYPE_ADAPTER_FACTORY + }; + + + /** + * Performs the Gson optimizations. + * + * @param programClassPool the program class pool on which to perform + * the Gson optimizations. + * @param libraryClassPool the library class pool used to look up + * library class references. + * @param injectedClassNameMap the map to which injected class names are + * added. + * @param configuration the DexGuard configuration that is applied. + * @throws IOException when the injected template classes can not + * be read. + */ + public void execute(ClassPool programClassPool, + ClassPool libraryClassPool, + MultiValueMap injectedClassNameMap, + Configuration configuration) throws IOException + { + // Set all fields of Gson to public. + programClassPool.classesAccept( + new ClassNameFilter(StringUtil.join(",", + NAME_GSON, + NAME_EXCLUDER), + new AllFieldVisitor( + new MemberAccessSetter(ClassConstants.ACC_PUBLIC)))); + + // To allow mocking Gson instances in unit tests, we remove the + // final qualifier from the Gson class. + programClassPool.classesAccept( + new ClassNameFilter(NAME_GSON, + new MemberAccessFlagCleaner(ClassConstants.ACC_FINAL))); + + // Setup Gson context that represents how Gson is used in program + // class pool. + PrintWriter out = + new PrintWriter(System.out, true); + WarningPrinter notePrinter = + new WarningPrinter(out, configuration.note); + + GsonContext gsonContext = new GsonContext(); + gsonContext.setupFor(programClassPool, notePrinter); + + // Is there something to optimize at all? + if (gsonContext.gsonDomainClassPool.size() > 0) + { + + // Collect fields that need to be serialized and deserialized. + OptimizedJsonInfo serializationInfo = new OptimizedJsonInfo(); + OptimizedJsonInfo deserializationInfo = new OptimizedJsonInfo(); + + OptimizedJsonFieldCollector serializedFieldCollector = + new OptimizedJsonFieldCollector(serializationInfo, + OptimizedJsonFieldCollector.Mode.serialize); + OptimizedJsonFieldCollector deserializedFieldCollector = + new OptimizedJsonFieldCollector(deserializationInfo, + OptimizedJsonFieldCollector.Mode.deserialize); + + gsonContext.gsonDomainClassPool + .classesAccept( + new MultiClassVisitor( + new OptimizedJsonFieldVisitor(serializedFieldCollector, + serializedFieldCollector), + new OptimizedJsonFieldVisitor(deserializedFieldCollector, + deserializedFieldCollector))); + + // Delete all @SerializedName and @Expose annotations + gsonContext.gsonDomainClassPool + .classesAccept(new GsonAnnotationCleaner(gsonContext.gsonRuntimeSettings)); + + // Assign random indices to classes and fields. + serializationInfo.assignIndices(); + deserializationInfo.assignIndices(); + + // Inject all serialization and deserialization template classes. + ClassReader helperClassReader = + new ClassReader(false, false, false, null, + new MultiClassVisitor( + new ClassPresenceFilter(programClassPool, null, + new ClassPoolFiller(programClassPool)), + new ClassReferenceInitializer(programClassPool, libraryClassPool), + new ClassSubHierarchyInitializer())); + + for (String clazz : TEMPLATE_CLASSES) + { + helperClassReader.read(new ClassPathDataEntry(clazz + CLASS_FILE_EXTENSION)); + injectedClassNameMap.put(GsonClassConstants.NAME_GSON, + clazz); + } + + // Inject serialization and deserialization data structures in + // _OptimizedJsonReaderImpl and _OptimizedJsonWriterImpl. + BranchTargetFinder branchTargetFinder = new BranchTargetFinder(); + CodeAttributeEditor codeAttributeEditor = + new CodeAttributeEditor(true, false); + + programClassPool + .classesAccept(NAME_OPTIMIZED_JSON_WRITER_IMPL, + new MultiClassVisitor( + new AllMemberVisitor( + new MemberNameFilter(OptimizedClassConstants.METHOD_NAME_INIT_NAMES, + new MemberDescriptorFilter(OptimizedClassConstants.METHOD_TYPE_INIT_NAMES, + new AllAttributeVisitor( + new OptimizedJsonWriterImplInitializer(programClassPool, + libraryClassPool, + codeAttributeEditor, + serializationInfo))))))); + + programClassPool + .classesAccept(NAME_OPTIMIZED_JSON_READER_IMPL, + new MultiClassVisitor( + new AllMemberVisitor( + new MemberNameFilter(OptimizedClassConstants.METHOD_NAME_INIT_NAMES_MAP, + new MemberDescriptorFilter(OptimizedClassConstants.METHOD_TYPE_INIT_NAMES_MAP, + new AllAttributeVisitor( + new OptimizedJsonReaderImplInitializer(programClassPool, + libraryClassPool, + codeAttributeEditor, + deserializationInfo))))))); + + // Inject serialization and deserialization code in domain classes. + gsonContext.gsonDomainClassPool + .classesAccept(new ClassAccessFilter(0, ACC_ENUM, + new GsonSerializationOptimizer(programClassPool, + libraryClassPool, + gsonContext.gsonRuntimeSettings, + codeAttributeEditor, + serializationInfo, + injectedClassNameMap))); + gsonContext.gsonDomainClassPool + .classesAccept(new ClassAccessFilter(0, ACC_ENUM, + new GsonDeserializationOptimizer(programClassPool, + libraryClassPool, + gsonContext.gsonRuntimeSettings, + codeAttributeEditor, + deserializationInfo, + injectedClassNameMap))); + gsonContext.gsonDomainClassPool + .classesAccept(new ClassReferenceInitializer(programClassPool, libraryClassPool)); + + // Inject type adapters for all serialized and deserialized classes. + Map typeAdapterRegistry = new HashMap(); + OptimizedTypeAdapterAdder optimizedTypeAdapterAdder = + new OptimizedTypeAdapterAdder(programClassPool, + libraryClassPool, + codeAttributeEditor, + serializationInfo, + deserializationInfo, + injectedClassNameMap, + typeAdapterRegistry, + gsonContext.instanceCreatorClassPool); + + gsonContext.gsonDomainClassPool.classesAccept(optimizedTypeAdapterAdder); + + // Implement type adapter factory. + programClassPool.classAccept(NAME_OPTIMIZED_TYPE_ADAPTER_FACTORY, + new MultiClassVisitor( + new AllMemberVisitor( + new AllAttributeVisitor( + new PeepholeOptimizer(branchTargetFinder, codeAttributeEditor, + new OptimizedTypeAdapterFactoryInitializer(programClassPool, + codeAttributeEditor, + typeAdapterRegistry, + gsonContext.gsonRuntimeSettings)))), + new ClassReferenceInitializer(programClassPool, libraryClassPool))); + + + // Add excluder field to Gson class if not present to support + // @Expose in earlier Gson versions (down to 2.1). + ProgramClass gsonClass = (ProgramClass) programClassPool.getClass(NAME_GSON); + MemberCounter memberCounter = new MemberCounter(); + gsonClass.accept(new NamedFieldVisitor(FIELD_NAME_EXCLUDER, + FIELD_TYPE_EXCLUDER, + memberCounter)); + boolean addExcluder = memberCounter.getCount() == 0; + if (addExcluder) + { + ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(gsonClass, + programClassPool, + libraryClassPool); + + int nameIndex = constantPoolEditor.addUtf8Constant(FIELD_NAME_EXCLUDER); + int descriptorIndex = constantPoolEditor.addUtf8Constant(FIELD_TYPE_EXCLUDER); + ProgramField field = new ProgramField(ClassConstants.ACC_PUBLIC, + nameIndex, + descriptorIndex, + null); + + ClassEditor classEditor = new ClassEditor(gsonClass); + classEditor.addField(field); + gsonClass.fieldsAccept(new ClassReferenceInitializer(programClassPool, libraryClassPool)); + gsonClass.constantPoolEntriesAccept(new ClassReferenceInitializer(programClassPool, libraryClassPool)); + } + + // Inject code that registers inject type adapter factory for optimized domain classes in Gson constructor. + programClassPool.classAccept(NAME_GSON, + new MultiClassVisitor( + new AllMemberVisitor( + new MemberNameFilter(ClassConstants.METHOD_NAME_INIT, + new GsonConstructorPatcher(codeAttributeEditor, addExcluder))), + new ClassReferenceInitializer(programClassPool, libraryClassPool))); + + if (configuration.verbose) + { + System.out.println(" Number of optimized serializable classes: " + gsonContext.gsonDomainClassPool.size() ); + } + + if (DEBUG) + { + // Inject instrumentation code in Gson.toJson() and Gson.fromJson(). + programClassPool.classAccept(NAME_GSON, + new AllMethodVisitor( + new MultiMemberVisitor( + new MemberNameFilter(GsonClassConstants.METHOD_NAME_TO_JSON, + new MemberDescriptorFilter(StringUtil.join(",", + GsonClassConstants.METHOD_TYPE_TO_JSON_OBJECT_TYPE_WRITER, + GsonClassConstants.METHOD_TYPE_TO_JSON_JSON_ELEMENT_WRITER), + new AllAttributeVisitor( + new PeepholeOptimizer(branchTargetFinder, codeAttributeEditor, + new GsonInstrumentationAdder(programClassPool, + libraryClassPool, + codeAttributeEditor))))), + + new MemberNameFilter(GsonClassConstants.METHOD_NAME_FROM_JSON, + new MemberDescriptorFilter(GsonClassConstants.METHOD_TYPE_FROM_JSON_JSON_READER_TYPE, + new AllAttributeVisitor( + new PeepholeOptimizer(branchTargetFinder, codeAttributeEditor, + new GsonInstrumentationAdder(programClassPool, + libraryClassPool, + codeAttributeEditor)))))))); + } + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonRuntimeSettings.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonRuntimeSettings.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonRuntimeSettings.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonRuntimeSettings.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +/** + * This class keeps track of which parameters of the GsonBuilder are being + * utilized in the code. + * + * @author Lars Vandenbergh + */ +public class GsonRuntimeSettings +{ + public boolean setVersion; + public boolean excludeFieldsWithModifiers; + public boolean generateNonExecutableJson; + public boolean excludeFieldsWithoutExposeAnnotation; + public boolean serializeNulls; + + // This setting is taken care of by the built-in MapTypeAdapterFactory + // of Gson. + // public boolean enableComplexMapKeySerialization; + + public boolean disableInnerClassSerialization; + public boolean setLongSerializationPolicy; + public boolean setFieldNamingPolicy; + public boolean setFieldNamingStrategy; + public boolean setExclusionStrategies; + public boolean addSerializationExclusionStrategy; + public boolean addDeserializationExclusionStrategy; + + // These settings on the builder are taken care of by the JsonWriter and + // JsonReader and don't affect our optimizations. + // public boolean setPrettyPrinting; + // public boolean setLenient; + // public boolean disableHtmlEscaping; + + // This setting is taken care of by the built-in DateTypeAdapters of Gson. + // public boolean setDateFormat; + + // These type adapters come before the _OptimizedTypeAdapterFactory we + // inject. + // public boolean registerTypeAdapter; + // public boolean registerTypeAdapterFactory; + // public boolean registerTypeHierarchyAdapter; + + public boolean serializeSpecialFloatingPointValues; +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonSerializationInvocationFinder.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonSerializationInvocationFinder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonSerializationInvocationFinder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonSerializationInvocationFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,266 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.Constant; +import proguard.classfile.editor.InstructionSequenceBuilder; +import proguard.classfile.instruction.Instruction; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.evaluation.BasicInvocationUnit; +import proguard.evaluation.value.*; +import proguard.optimize.evaluation.PartialEvaluator; + +/** + * This instruction visitor searches the code for invocations to any of the + * serialization methods of Gson (all the toJson variants) and keeps + * track of the domain classes that are involved in the serialization. + * + * @author Lars Vandenbergh + */ +public class GsonSerializationInvocationFinder +extends SimplifiedVisitor +implements InstructionVisitor +{ + private static final boolean DEBUG = false; + + private final ClassPool programClassPool; + private final ClassVisitor domainClassVisitor; + private final WarningPrinter notePrinter; + private final ToJsonInvocationMatcher[] toJsonInvocationMatchers; + private final TypedReferenceValueFactory valueFactory = + new TypedReferenceValueFactory(); + private final PartialEvaluator partialEvaluator = + new PartialEvaluator(valueFactory, + new BasicInvocationUnit(new TypedReferenceValueFactory()), + true); + private final AttributeVisitor lazyPartialEvaluator = + new AttributeNameFilter(ClassConstants.ATTR_Code, + new SingleTimeAttributeVisitor(partialEvaluator)); + + + /** + * Creates a new GsonSerializationInvocationFinder. + * + * @param programClassPool the program class pool used to look up class + * references. + * @param domainClassVisitor the visitor to which found domain classes that + * are involved in Gson serialization will + * be delegated. + * @param notePrinter used to print notes about domain classes that + * can not be handled by the Gson optimization. + */ + public GsonSerializationInvocationFinder(ClassPool programClassPool, + ClassVisitor domainClassVisitor, + WarningPrinter notePrinter) + { + this.programClassPool = programClassPool; + this.domainClassVisitor = domainClassVisitor; + this.notePrinter = notePrinter; + + // Create matchers for relevant instruction sequences. + InstructionSequenceBuilder builder = new InstructionSequenceBuilder(); + + // The invocation "Gson#toJson(Object)". + Instruction[] toJsonObjectInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON, + GsonClassConstants.METHOD_TYPE_TO_JSON_OBJECT) + .instructions(); + + // The invocation "Gson#toJson(Object, Type)". + Instruction[] toJsonObjectTypeInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON, + GsonClassConstants.METHOD_TYPE_TO_JSON_OBJECT_TYPE) + .instructions(); + + // The invocation "Gson#toJson(Object, Appendable)". + Instruction[] toJsonObjectAppendableInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON, + GsonClassConstants.METHOD_TYPE_TO_JSON_OBJECT_APPENDABLE) + .instructions(); + + // The invocation "Gson#toJson(Object, Type, Appendable)". + Instruction[] toJsonObjectTypeAppendableInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON, + GsonClassConstants.METHOD_TYPE_TO_JSON_OBJECT_TYPE_APPENDABLE) + .instructions(); + + // The invocation "Gson#toJson(Object, Type, JsonWriter)". + Instruction[] toJsonObjectTypeWriterInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON, + GsonClassConstants.METHOD_TYPE_TO_JSON_OBJECT_TYPE_WRITER) + .instructions(); + + // The invocation "Gson#toJsonTree(Object)". + Instruction[] toJsonTreeObjectInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON_TREE, + GsonClassConstants.METHOD_TYPE_TO_JSON_TREE_OBJECT) + .instructions(); + + // The invocation "Gson#toJsonTree(Object, Type)". + Instruction[] toJsonTreeObjectTypeInstructions = builder + .invokevirtual(GsonClassConstants.NAME_GSON, + GsonClassConstants.METHOD_NAME_TO_JSON_TREE, + GsonClassConstants.METHOD_TYPE_TO_JSON_TREE_OBJECT_TYPE) + .instructions(); + + Constant[] constants = builder.constants(); + + toJsonInvocationMatchers = new ToJsonInvocationMatcher[] + { + new ToJsonInvocationMatcher(constants, toJsonObjectInstructions , 0, -1), + new ToJsonInvocationMatcher(constants, toJsonObjectTypeInstructions , 1, 0), + new ToJsonInvocationMatcher(constants, toJsonObjectAppendableInstructions , 1, -1), + new ToJsonInvocationMatcher(constants, toJsonObjectTypeAppendableInstructions, 2, 1), + new ToJsonInvocationMatcher(constants, toJsonObjectTypeWriterInstructions , 2, 1), + new ToJsonInvocationMatcher(constants, toJsonTreeObjectInstructions , 0, -1), + new ToJsonInvocationMatcher(constants, toJsonTreeObjectTypeInstructions , 1, 0) + }; + } + + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + // Try to match any of the toJson() constructs. + ToJsonInvocationMatcher matchingMatcher = null; + for (ToJsonInvocationMatcher matcher : toJsonInvocationMatchers) + { + instruction.accept(clazz, + method, + codeAttribute, + offset, + matcher); + if(matcher.isMatching()) + { + matchingMatcher = matcher; + break; + } + } + + if (matchingMatcher != null) + { + if (DEBUG) + { + System.out.println("GsonSerializationInvocationFinder: Gson#toJson/toJsonTree: " + + clazz.getName() + + "." + + method.getName(clazz) + + method.getDescriptor(clazz) + + " " + + instruction.toString(offset)); + } + + // Figure out the type that is being serialized. + lazyPartialEvaluator.visitCodeAttribute(clazz, + method, + codeAttribute); + + if (matchingMatcher.typeStackElementIndex == -1) + { + // Derive type from Object argument. + int stackElementIndex = matchingMatcher.objectStackElementIndex; + ReferenceValue top = partialEvaluator.getStackBefore(offset) + .getTop(stackElementIndex) + .referenceValue(); + Clazz targetClass = top.getReferencedClass(); + + if (targetClass instanceof ProgramClass) + { + targetClass.accept(domainClassVisitor); + } + } + else + { + // Derive types from Type argument. + int stackElementIndex = matchingMatcher.typeStackElementIndex; + InstructionOffsetValue producer = + partialEvaluator.getStackBefore(offset) + .getTopActualProducerValue(stackElementIndex) + .instructionOffsetValue(); + + TypeArgumentFinder typeArgumentFinder = + new TypeArgumentFinder(programClassPool, partialEvaluator); + for (int i = 0; i < producer.instructionOffsetCount(); i++) + { + codeAttribute.instructionAccept(clazz, + method, + producer.instructionOffset(i), + typeArgumentFinder); + } + + String[] targetTypes = typeArgumentFinder.typeArgumentClasses; + if (targetTypes != null) + { + for (String targetType : targetTypes) + { + programClassPool.classAccept(targetType, domainClassVisitor); + } + } + else if (notePrinter != null) + { + notePrinter.print(clazz.getName(), + "Warning: can't derive serialized type from toJson() invocation in " + + clazz.getName() + + "." + + method.getName(clazz) + + method.getDescriptor(clazz)); + } + } + } + } + + + // Utility classes. + + private static class ToJsonInvocationMatcher + extends InstructionSequenceMatcher + { + private int objectStackElementIndex; + private int typeStackElementIndex; + + private ToJsonInvocationMatcher(Constant[] patternConstants, + Instruction[] patternInstructions, + int objectStackElementIndex, + int typeStackElementIndex) + { + super(patternConstants, patternInstructions); + this.objectStackElementIndex = objectStackElementIndex; + this.typeStackElementIndex = typeStackElementIndex; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/GsonSerializationOptimizer.java proguard-6.2.0/core/src/proguard/optimize/gson/GsonSerializationOptimizer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/GsonSerializationOptimizer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/GsonSerializationOptimizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,503 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 Guardsquare NV + */ +package proguard.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.optimize.info.ProgramMemberOptimizationInfoSetter; +import proguard.util.MultiValueMap; + +import java.util.*; + +import static proguard.optimize.gson.OptimizedClassConstants.*; + +/** + * This visitor injects a toJson$xxx() method into the classes that it visits + * that serializes its fields to Json. + * + * @author Lars Vandenbergh + * @author Rob Coekaerts + */ +public class GsonSerializationOptimizer +extends SimplifiedVisitor +implements MemberVisitor, + ClassVisitor, + ElementValueVisitor, + AttributeVisitor, + AnnotationVisitor +{ + private static final boolean DEBUG = false; + + private static final Map inlineSerializers = new HashMap(); + + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final GsonRuntimeSettings gsonRuntimeSettings; + private final CodeAttributeEditor codeAttributeEditor; + private final OptimizedJsonInfo serializationInfo; + private final boolean supportExposeAnnotation; + private final MultiValueMap injectedClassNameMap; + + private InstructionSequenceBuilder ____; + + static + { + inlineSerializers.put(ClassConstants.TYPE_BOOLEAN + "", + new InlineSerializers.InlinePrimitiveBooleanSerializer()); + inlineSerializers.put(ClassConstants.TYPE_JAVA_LANG_BOOLEAN, + new InlineSerializers.InlineBooleanSerializer()); + inlineSerializers.put(ClassConstants.TYPE_BYTE + "", + new InlineSerializers.InlinePrimitiveIntegerSerializer()); + inlineSerializers.put(ClassConstants.TYPE_SHORT + "", + new InlineSerializers.InlinePrimitiveIntegerSerializer()); + inlineSerializers.put(ClassConstants.TYPE_INT + "", + new InlineSerializers.InlinePrimitiveIntegerSerializer()); + inlineSerializers.put(ClassConstants.TYPE_JAVA_LANG_STRING, + new InlineSerializers.InlineStringSerializer()); + } + + /** + * Creates a new GsonSerializationOptimizer. + * + * @param programClassPool the program class pool to initialize + * added references. + * @param libraryClassPool the library class pool to initialize + * added references. + * @param gsonRuntimeSettings keeps track of all GsonBuilder + * invocations. + * @param codeAttributeEditor the code editor that is used to + * inject optimized code into the domain + * classes. + * @param serializationInfo contains information on which class + * and fields need to be optimized and how. + * @param injectedClassNameMap the map that keeps track of injected + * classes. + */ + public GsonSerializationOptimizer(ClassPool programClassPool, + ClassPool libraryClassPool, + GsonRuntimeSettings gsonRuntimeSettings, + CodeAttributeEditor codeAttributeEditor, + OptimizedJsonInfo serializationInfo, + MultiValueMap injectedClassNameMap) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.gsonRuntimeSettings = gsonRuntimeSettings; + this.codeAttributeEditor = codeAttributeEditor; + this.serializationInfo = serializationInfo; + this.supportExposeAnnotation = gsonRuntimeSettings.excludeFieldsWithoutExposeAnnotation; + this.injectedClassNameMap = injectedClassNameMap; + } + + + // Implementations for ClassVisitor. + + public void visitAnyClass(Clazz clazz) {} + + + public void visitProgramClass(ProgramClass programClass) + { + // Make access public for _OptimizedTypeAdapterFactory. + programClass.u2accessFlags &= ~ClassConstants.ACC_PRIVATE; + programClass.u2accessFlags |= ClassConstants.ACC_PUBLIC; + + // Start adding new serialization methods. + SimplifiedClassEditor classEditor = + new SimplifiedClassEditor(programClass); + + ____ = new InstructionSequenceBuilder(programClass, + programClassPool, + libraryClassPool); + + // Add toJson$ method. + Integer classIndex = serializationInfo.classIndices.get(programClass.getName()); + String methodNameToJson = METHOD_NAME_TO_JSON + classIndex; + String methodNameToJsonBody = METHOD_NAME_TO_JSON_BODY + classIndex; + + if (DEBUG) + { + System.out.println( + "GsonSerializationOptimizer: adding " + + methodNameToJson + + " method to " + programClass.getName()); + } + + ProgramMethod toJsonMethod = classEditor.addMethod( + ClassConstants.ACC_PUBLIC | ClassConstants.ACC_SYNTHETIC, + methodNameToJson, + METHOD_TYPE_TO_JSON, + ____.return_() + .instructions()); + + toJsonMethod.accept(programClass, + new ProgramMemberOptimizationInfoSetter()); + + // Create new CodeAttributeEditor for the toJson$ method. + codeAttributeEditor.reset(1); + + // Begin Json object. + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_WRITER_BEGIN_OBJECT, + GsonClassConstants.METHOD_TYPE_WRITER_BEGIN_OBJECT); + + // Invoke toJsonBody$. + ____.aload(OptimizedClassConstants.ToJsonLocals.THIS) + .aload(OptimizedClassConstants.ToJsonLocals.GSON) + .aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.OPTIMIZED_JSON_WRITER) + .invokevirtual(programClass.getName(), + methodNameToJsonBody, + METHOD_TYPE_TO_JSON_BODY); + + // End Json object. + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_WRITER_END_OBJECT, + GsonClassConstants.METHOD_TYPE_WRITER_END_OBJECT) + .return_(); + + // Add all toJson$ instructions. + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + toJsonMethod.attributesAccept(programClass, codeAttributeEditor); + + addToJsonBodyMethod(programClass, classEditor); + + programClass.accept(new MethodLinker()); + + classEditor.finishEditing(programClassPool, + libraryClassPool); + } + + + private void addToJsonBodyMethod(ProgramClass programClass, + SimplifiedClassEditor classEditor) + { + Integer classIndex = serializationInfo.classIndices.get(programClass.getName()); + String methodName = METHOD_NAME_TO_JSON_BODY + classIndex; + + // Add toJsonBody$ method. + if (DEBUG) + { + System.out.println( + "GsonSerializationOptimizer: adding " + + methodName + + " method to " + programClass.getName()); + } + + + ProgramMethod toJsonBodyMethod = classEditor.addMethod( + ClassConstants.ACC_PROTECTED | ClassConstants.ACC_SYNTHETIC, + methodName, + METHOD_TYPE_TO_JSON_BODY, + ____.return_() + .instructions()); + + // Add optimization info to new method. + toJsonBodyMethod.accept(programClass, + new ProgramMemberOptimizationInfoSetter()); + + // Edit code attribute of fromJson$. + toJsonBodyMethod.attributesAccept(programClass, + new ToJsonCodeAttributeVisitor()); + } + + + private class ToJsonCodeAttributeVisitor + extends SimplifiedVisitor + implements AttributeVisitor, + MemberVisitor + { + private int valueLocalIndex; + + // Implementations for AttributeVisitor. + + @Override + public void visitCodeAttribute(Clazz clazz, + Method method, + CodeAttribute codeAttribute) + { + // Create new CodeAttributeEditor for the toJsonBody$ method. + codeAttributeEditor.reset(1); + + // Assign locals for nextFieldIndex and isNull. + valueLocalIndex = codeAttribute.u2maxLocals; + + // Apply non static member visitor to all fields to visit. + clazz.fieldsAccept(new MemberAccessFilter(0, + ClassConstants.ACC_SYNTHETIC | + ClassConstants.ACC_STATIC, + this)); + + // Call the superclass toJsonBody$ if there is one. + if (!clazz.getSuperClass().getName().equals(ClassConstants.NAME_JAVA_LANG_OBJECT)) + { + Integer superClassIndex = + serializationInfo.classIndices.get(clazz.getSuperClass().getName()); + String superMethodNameToJsonBody = METHOD_NAME_TO_JSON_BODY + superClassIndex; + + ____.aload(OptimizedClassConstants.ToJsonLocals.THIS) + .aload(OptimizedClassConstants.ToJsonLocals.GSON) + .aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.OPTIMIZED_JSON_WRITER) + .invokevirtual(clazz.getSuperClass().getName(), + superMethodNameToJsonBody, + METHOD_TYPE_TO_JSON_BODY); + } + + ____.return_(); + + // Add all toJsonBody$ instructions. + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + + + // Implementations for MemberVisitor. + + public void visitProgramField(ProgramClass programClass, + ProgramField programField) + { + OptimizedJsonInfo.ClassJsonInfo classSerializationInfo = + serializationInfo.classJsonInfos.get(programClass.getName()); + String[] jsonFieldNames = classSerializationInfo.javaToJsonFieldNames.get(programField.getName(programClass)); + String javaFieldName = programField.getName(programClass); + + if (jsonFieldNames != null) + { + // Derive field descriptor and signature (if it exists). + String fieldDescriptor = programField.getDescriptor(programClass); + FieldSignatureCollector signatureAttributeCollector = new FieldSignatureCollector(); + programField.attributesAccept(programClass, signatureAttributeCollector); + boolean retrieveAdapterByTypeToken = false; + + // Check for recursion first if it is an object + CodeAttributeEditor.Label end = codeAttributeEditor.label(); + if(ClassUtil.isInternalClassType(fieldDescriptor)) + { + CodeAttributeEditor.Label noRecursion = codeAttributeEditor.label(); + ____.aload(OptimizedClassConstants.ToJsonLocals.THIS) + .aload(OptimizedClassConstants.ToJsonLocals.THIS) + .getfield(programClass, programField) + .ifacmpne(noRecursion.offset()) + .goto_(end.offset()) + .label(noRecursion); + } + + if (supportExposeAnnotation && + !classSerializationInfo.exposedJavaFieldNames.contains(javaFieldName)) + { + ____.aload(ToJsonLocals.GSON) + .getfield(GsonClassConstants.NAME_GSON, FIELD_NAME_EXCLUDER, FIELD_TYPE_EXCLUDER) + .getfield(GsonClassConstants.NAME_EXCLUDER, FIELD_NAME_REQUIRE_EXPOSE, FIELD_TYPE_REQUIRE_EXPOSE) + .ifne(end.offset()); + } + + + // Write field name. + Integer fieldIndex = serializationInfo.jsonFieldIndices.get(jsonFieldNames[0]); + ____.aload(OptimizedClassConstants.ToJsonLocals.OPTIMIZED_JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .ldc(fieldIndex.intValue()) + .invokeinterface(OptimizedClassConstants.NAME_OPTIMIZED_JSON_WRITER, + OptimizedClassConstants.METHOD_NAME_NAME, + OptimizedClassConstants.METHOD_TYPE_NAME); + + // Write field value. + InlineSerializer inlineSerializer = inlineSerializers.get(fieldDescriptor); + if (inlineSerializer != null && + inlineSerializer.canSerialize(programClassPool, gsonRuntimeSettings)) + { + inlineSerializer.serialize(programClass, + programField, + codeAttributeEditor, + ____, + gsonRuntimeSettings); + } + else + { + // Write value to Json writer based on declared type and runtime value/type. + ____.aload(OptimizedClassConstants.ToJsonLocals.GSON); + + switch (fieldDescriptor.charAt(0)) + { + case ClassConstants.TYPE_BOOLEAN: + case ClassConstants.TYPE_CHAR: + case ClassConstants.TYPE_BYTE: + case ClassConstants.TYPE_SHORT: + case ClassConstants.TYPE_INT: + case ClassConstants.TYPE_FLOAT: + case ClassConstants.TYPE_LONG: + case ClassConstants.TYPE_DOUBLE: + { + String className = ClassUtil.internalNumericClassNameFromPrimitiveType(fieldDescriptor.charAt(0)); + ____.getstatic(className, ClassConstants.FIELD_NAME_TYPE, ClassConstants.FIELD_TYPE_TYPE); + break; + } + case ClassConstants.TYPE_CLASS_START: + { + if (signatureAttributeCollector.getFieldSignature() == null) + { + String fieldClassName = fieldDescriptor.substring(1, fieldDescriptor.length() - 1); + Clazz fieldClass = programClassPool.getClass(fieldClassName); + if (fieldClass == null) + { + fieldClass = libraryClassPool.getClass(fieldClassName); + } + ____.ldc(fieldClassName, fieldClass); + } + else + { + // Add type token sub-class that has the appropriate type parameter. + ProgramClass typeTokenClass = + new TypeTokenClassBuilder(programClass, + programField, + signatureAttributeCollector.getFieldSignature()) + .build(programClassPool); + programClassPool.addClass(typeTokenClass); + typeTokenClass.accept(new ClassReferenceInitializer(programClassPool, + libraryClassPool)); + injectedClassNameMap.put(programClass.getName(), typeTokenClass.getName()); + + // Instantiate type token. + ____.new_(typeTokenClass.getName()) + .dup() + .invokespecial(typeTokenClass.getName(), + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT); + retrieveAdapterByTypeToken = true; + } + break; + } + case ClassConstants.TYPE_ARRAY: + { + int fieldDescriptorIndex = 1; + while (fieldDescriptor.charAt(fieldDescriptorIndex) == ClassConstants.TYPE_ARRAY) + { + fieldDescriptorIndex++; + } + + Clazz fieldClass; + switch (fieldDescriptor.charAt(fieldDescriptorIndex)) + { + case ClassConstants.TYPE_BOOLEAN: + case ClassConstants.TYPE_CHAR: + case ClassConstants.TYPE_BYTE: + case ClassConstants.TYPE_SHORT: + case ClassConstants.TYPE_INT: + case ClassConstants.TYPE_FLOAT: + case ClassConstants.TYPE_LONG: + case ClassConstants.TYPE_DOUBLE: + { + String className = ClassUtil.internalNumericClassNameFromPrimitiveType(fieldDescriptor.charAt(0)); + fieldClass = libraryClassPool.getClass(className); + ____.ldc(fieldDescriptor, fieldClass); + break; + } + case ClassConstants.TYPE_CLASS_START: + { + String fieldClassName = fieldDescriptor.substring(2, fieldDescriptor.length() - 1); + fieldClass = programClassPool.getClass(fieldClassName); + if (fieldClass == null) + { + fieldClass = libraryClassPool.getClass(fieldClassName); + } + ____.ldc(fieldDescriptor, fieldClass); + break; + } + } + break; + } + } + + ____.aload(OptimizedClassConstants.ToJsonLocals.THIS) + .getfield(programClass, programField); + + // Box primitive value before passing it to type adapter. + switch (fieldDescriptor.charAt(0)) + { + case ClassConstants.TYPE_BOOLEAN: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_BOOLEAN, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_BOOLEAN); + break; + case ClassConstants.TYPE_CHAR: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_CHARACTER, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_CHAR); + break; + case ClassConstants.TYPE_BYTE: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_BYTE, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_BYTE); + break; + case ClassConstants.TYPE_SHORT: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_SHORT, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_SHORT); + break; + case ClassConstants.TYPE_INT: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_INTEGER, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_INT); + break; + case ClassConstants.TYPE_FLOAT: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_FLOAT, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_FLOAT); + break; + case ClassConstants.TYPE_LONG: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_LONG, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_LONG); + break; + case ClassConstants.TYPE_DOUBLE: + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_DOUBLE, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_DOUBLE); + break; + } + + // Copy value to local. + ____.dup() + .astore(valueLocalIndex); + + // Retrieve type adapter. + if(retrieveAdapterByTypeToken) + { + ____.invokestatic(OptimizedClassConstants.NAME_GSON_UTIL, + OptimizedClassConstants.METHOD_NAME_GET_TYPE_ADAPTER_TYPE_TOKEN, + OptimizedClassConstants.METHOD_TYPE_GET_TYPE_ADAPTER_TYPE_TOKEN); + } + else + { + ____.invokestatic(OptimizedClassConstants.NAME_GSON_UTIL, + OptimizedClassConstants.METHOD_NAME_GET_TYPE_ADAPTER_CLASS, + OptimizedClassConstants.METHOD_TYPE_GET_TYPE_ADAPTER_CLASS); + } + + // Write value using type adapter. + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(valueLocalIndex) + .invokevirtual(GsonClassConstants.NAME_TYPE_ADAPTER, + GsonClassConstants.METHOD_NAME_WRITE, + GsonClassConstants.METHOD_TYPE_WRITE); + } + + // Label for skipping writing of field in case of recursion or + // a non-exposed field with excludeFieldsWithoutExposeAnnotation + // enabled. + ____.label(end); + } + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_GsonUtil.java proguard-6.2.0/core/src/proguard/optimize/gson/_GsonUtil.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_GsonUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_GsonUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,143 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.*; +import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.*; +import java.util.Map; + +/** + * This utility class is injected into the program class pool when the GSON + * optimizations are applied. It contains the logic for picking the right + * type adapter for a given type and value that needs to be serialized. + * + * The injected toJson() methods in the domain classes will use these utility + * methods for serializing the fields of the domain class with the appropriate + * type adapter. + * + * @author Lars Vandenbergh + */ +public final class _GsonUtil +{ + /** + * Returns the appropriate type adapter for handling the given value with + * the given declared type. + * + * @param gson the Gson context that manages all registered type + * adapters. + * @param declaredType the type of the value to (de)serialize. + * @param value the value to (de)serialize. + * @return the type adapter for handling the given value and + * declared type. + */ + public static TypeAdapter getTypeAdapter(Gson gson, Class declaredType, Object value) + { + // If the runtime type is a sub type and there is a custom type adapter registered for + // the declared type, that one should get precedence over the runtime type adapter if + // the runtime type adapter is not custom. + Type runtimeType = getRuntimeTypeIfMoreSpecific(declaredType, value); + TypeAdapter runtimeTypeAdapter = gson.getAdapter(TypeToken.get(runtimeType)); + if (declaredType != runtimeType && !isCustomTypeAdapter(runtimeTypeAdapter)) + { + TypeAdapter declaredTypeAdapter = gson.getAdapter(declaredType); + if (isCustomTypeAdapter(declaredTypeAdapter)) + { + return declaredTypeAdapter; + } + } + + // In all other cases the type adapter for the runtime type is used. + return runtimeTypeAdapter; + } + + + /** + * Returns the appropriate type adapter for handling the given value with + * the given declared type token. + * + * @param gson the Gson context that manages all registered type + * adapters. + * @param declaredTypeToken the declared type token of the value to (de)serialize. + * @param value the value to (de)serialize. + * @return the type adapter for handling the given value and + * declared type. + */ + public static TypeAdapter getTypeAdapter(Gson gson, TypeToken declaredTypeToken, Object value) + { + // If the runtime type is a sub type and there is a custom type adapter registered for + // the declared type, that one should get precedence over the runtime type adapter if + // the runtime type adapter is not custom. + Type declaredType = declaredTypeToken.getType(); + Type runtimeType = getRuntimeTypeIfMoreSpecific(declaredType, value); + TypeAdapter runtimeTypeAdapter = gson.getAdapter(TypeToken.get(runtimeType)); + if (declaredType != runtimeType && !isCustomTypeAdapter(runtimeTypeAdapter)) + { + TypeAdapter declaredTypeAdapter = gson.getAdapter(declaredTypeToken); + if (isCustomTypeAdapter(declaredTypeAdapter)) + { + return declaredTypeAdapter; + } + } + + // In all other cases the type adapter for the runtime type is used. + return runtimeTypeAdapter; + } + + + /** + * Finds a compatible runtime type if it is more specific + */ + private static Type getRuntimeTypeIfMoreSpecific(Type type, Object value) { + if (value != null + && (type == Object.class || type instanceof TypeVariable || type instanceof Class)) { + type = value.getClass(); + } + return type; + } + + /** + * Determines whether a given type adapter is a custom type adapter, i.e. + * a type adapter that is registered by the user of the Gson API and not + * the GSON reflection based type adapter or the optimized type adapter + * injected by DexGuard. + */ + private static boolean isCustomTypeAdapter(TypeAdapter declaredTypeAdapter) + { + return !(declaredTypeAdapter instanceof _OptimizedTypeAdapter) && + !(declaredTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter); + } + + + /** + * Dumps the cached type adapter for each type for debugging purpose. + */ + public static void dumpTypeTokenCache(String message, Map, TypeAdapter> typeTokenCache) + { + System.out.println(message); + for (Map.Entry, TypeAdapter> typeTokenCacheEntry : typeTokenCache.entrySet()) + { + System.out.println(" " + typeTokenCacheEntry.getKey() + " -> " + typeTokenCacheEntry.getValue()); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/InlineDeserializer.java proguard-6.2.0/core/src/proguard/optimize/gson/InlineDeserializer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/InlineDeserializer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/InlineDeserializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,70 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.editor.*; + +/** + * Interface for injecting optimized code for deserializing a field of a class + * from Json. + * + * @author Lars Vandenbergh + */ +interface InlineDeserializer +{ + /** + * Indicates whether the deserializer can inject optimized code given which + * GSON builder invocations are utilized in the program code. + * + * @param gsonRuntimeSettings tracks the GSON parameters that are utilized + * in the code. + * @return true if and only if the deserializer can inject optimized code. + */ + boolean canDeserialize(GsonRuntimeSettings gsonRuntimeSettings); + + /** + * Appends optimized code for deserializing the given field of the given class + * using the given code attribute editor and instruction sequence builder. + * + * The current locals are: + * 0 this (the domain object) + * 1 gson + * 2 jsonReader + * 3 fieldIndex + * + * @param programClass The domain class containing the field to + * deserialize. + * @param programField The field of the domain class to + * deserialize. + * @param codeAttributeEditor the code attribute editor to be used for + * injecting instructions. + * @param builder the instruction sequence builder to be used + * for generating instructions. + * @param gsonRuntimeSettings tracks the GSON parameters that are utilized + * in the code. + */ + void deserialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder builder, + GsonRuntimeSettings gsonRuntimeSettings); +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/InlineDeserializers.java proguard-6.2.0/core/src/proguard/optimize/gson/InlineDeserializers.java --- proguard-6.0.3/core/src/proguard/optimize/gson/InlineDeserializers.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/InlineDeserializers.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,180 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.editor.*; + +/** + * Class that groups all InlineDeserializer implementations for common types + * together. + * + * @author Lars Vandenbergh + */ +class InlineDeserializers +{ + /** + * Deserializer for handling primitive int, short and byte values. + */ + static class InlinePrimitiveIntegerDeserializer implements InlineDeserializer + { + private final Class targetType; + + + public InlinePrimitiveIntegerDeserializer() + { + this(null); + } + + + public InlinePrimitiveIntegerDeserializer(Class targetType) + { + this.targetType = targetType; + } + + + // Implementations for InlineDeserializer. + + @Override + public boolean canDeserialize(GsonRuntimeSettings gsonRuntimeSettings) + { + return true; + } + + @Override + public void deserialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder ____, + GsonRuntimeSettings gsonRuntimeSettings) + { + // Create labels for exception table. + ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(programClass); + int exceptionClassConstant = + constantPoolEditor.addClassConstant(ClassConstants.NAME_JAVA_LANG_NUMBER_FORMAT_EXCEPTION, + null); + + CodeAttributeEditor.Label tryStart = codeAttributeEditor.label(); + CodeAttributeEditor.Label tryEnd = codeAttributeEditor.label(); + CodeAttributeEditor.Label catchStart = + codeAttributeEditor.catch_(tryStart.offset(), + tryEnd.offset(), + exceptionClassConstant); + CodeAttributeEditor.Label catchEnd = codeAttributeEditor.label(); + + // Try to read and parse integer. + ____.label(tryStart) + .aload(OptimizedClassConstants.FromJsonLocals.THIS) + .aload(OptimizedClassConstants.FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_NEXT_INTEGER, + GsonClassConstants.METHOD_TYPE_NEXT_INTEGER); + + // Convert if necessary. + if (targetType == byte.class) + { + ____.i2b(); + } + else if (targetType == short.class) + { + ____.i2s(); + } + + // Assign it to the field + ____.putfield(programClass, programField) + .goto_(catchEnd.offset()) + .label(tryEnd); + + // Throw JsonSyntaxException if reading and parsing the integer failed. + int throwableLocal = OptimizedClassConstants.FromJsonLocals.MAX_LOCALS + 1; + ____.label(catchStart) + .astore(throwableLocal) + .new_(GsonClassConstants.NAME_JSON_SYNTAX_EXCEPTION) + .dup() + .aload(throwableLocal) + .invokespecial(GsonClassConstants.NAME_JSON_SYNTAX_EXCEPTION, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT_THROWABLE) + .athrow() + .label(catchEnd); + } + } + + + /** + * Deserializer for handling String values. + */ + static class InlineStringDeserializer implements InlineDeserializer + { + // Implementations for InlineDeserializer. + + @Override + public boolean canDeserialize(GsonRuntimeSettings gsonRuntimeSettings) + { + return true; + } + + @Override + public void deserialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder ____, + GsonRuntimeSettings gsonRuntimeSettings) + { + CodeAttributeEditor.Label isBoolean = codeAttributeEditor.label(); + CodeAttributeEditor.Label end = codeAttributeEditor.label(); + + // Peek value and check whether it is a boolean. + ____.aload(OptimizedClassConstants.FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_PEEK, + GsonClassConstants.METHOD_TYPE_PEEK) + .getstatic(GsonClassConstants.NAME_JSON_TOKEN, + GsonClassConstants.FIELD_NAME_BOOLEAN, + GsonClassConstants.FIELD_TYPE_BOOLEAN) + .ifacmpeq(isBoolean.offset()); + + // It's not a boolean, just read the String and assign it to the + // field. + ____.aload(OptimizedClassConstants.FromJsonLocals.THIS) + .aload(OptimizedClassConstants.FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_NEXT_STRING, + GsonClassConstants.METHOD_TYPE_NEXT_STRING) + .putfield(programClass, programField) + .goto_(end.offset()); + + // It's a boolean, convert it to a String first and then assign it + // to the field. + ____.label(isBoolean) + .aload(OptimizedClassConstants.FromJsonLocals.THIS) + .aload(OptimizedClassConstants.FromJsonLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_NEXT_BOOLEAN, + GsonClassConstants.METHOD_TYPE_NEXT_BOOLEAN) + .invokestatic(ClassConstants.NAME_JAVA_LANG_BOOLEAN, + ClassConstants.METHOD_NAME_TOSTRING, + ClassConstants.METHOD_TYPE_TOSTRING_BOOLEAN) + .putfield(programClass, programField) + .label(end); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/InlineSerializer.java proguard-6.2.0/core/src/proguard/optimize/gson/InlineSerializer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/InlineSerializer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/InlineSerializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.editor.*; + +/** + * Interface for injecting optimized code for serializing a field of a class + * to Json. + * + * @author Lars Vandenbergh + */ +interface InlineSerializer +{ + /** + * Indicates whether the serializer can inject optimized code given which + * GSON builder invocations are utilized in the program code. + * + * @param programClassPool The class pool containing the program classes. + * @param gsonRuntimeSettings tracks the GSON parameters that are utilized + * in the code. + * @return true if and only if the serializer can inject optimized code. + */ + boolean canSerialize(ClassPool programClassPool, + GsonRuntimeSettings gsonRuntimeSettings); + + /** + * Appends optimized code for serializing the given field of the given class + * using the given code attribute editor and instruction sequence builder. + * + * The current locals are: + * 0 this (the domain object) + * 1 gson + * 2 jsonWriter + * 3 optimizedJsonWriter + * + * @param programClass The domain class containing the field to + * serialize. + * @param programField The field of the domain class to serialize. + * @param codeAttributeEditor the code attribute editor to be used for + * injecting instructions. + * @param builder the instruction sequence builder to be used + * for generating instructions. + * @param gsonRuntimeSettings tracks the GSON parameters that are utilized + * in the code. + */ + void serialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder builder, + GsonRuntimeSettings gsonRuntimeSettings); +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/InlineSerializers.java proguard-6.2.0/core/src/proguard/optimize/gson/InlineSerializers.java --- proguard-6.0.3/core/src/proguard/optimize/gson/InlineSerializers.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/InlineSerializers.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,171 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.editor.*; + +/** + * Class that groups all InlineSerializer implementations for common types + * together. + * + * @author Lars Vandenbergh + */ +class InlineSerializers +{ + /** + * Serializer for primitive boolean values. + */ + static class InlinePrimitiveBooleanSerializer implements InlineSerializer + { + // Implementations for InlineSerializer. + + @Override + public boolean canSerialize(ClassPool programClassPool, + GsonRuntimeSettings gsonRuntimeSettings) + { + return true; + } + + + @Override + public void serialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder ____, + GsonRuntimeSettings gsonRuntimeSettings) + { + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.THIS) + .getfield(programClass, programField) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_VALUE_BOOLEAN, + GsonClassConstants.METHOD_TYPE_VALUE_BOOLEAN) + .pop(); + } + } + + /** + * Serializer for handling Boolean values. + */ + static class InlineBooleanSerializer implements InlineSerializer + { + // Implementations for InlineSerializer. + + @Override + public boolean canSerialize(ClassPool programClassPool, + GsonRuntimeSettings gsonRuntimeSettings) + { + // Check whether JsonWriter.value(Boolean) is present in the used + // version of Gson (should be from Gson 2.7 onwards). + Clazz jsonWriterClass = + programClassPool.getClass(GsonClassConstants.NAME_JSON_WRITER); + Method valueBooleanMethod = + jsonWriterClass.findMethod(GsonClassConstants.METHOD_NAME_VALUE_BOOLEAN_OBJECT, + GsonClassConstants.METHOD_TYPE_VALUE_BOOLEAN_OBJECT); + return valueBooleanMethod != null; + } + + + @Override + public void serialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder ____, + GsonRuntimeSettings gsonRuntimeSettings) + { + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.THIS) + .getfield(programClass, programField) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_VALUE_BOOLEAN_OBJECT, + GsonClassConstants.METHOD_TYPE_VALUE_BOOLEAN_OBJECT) + .pop(); + } + } + + /** + * Serializer for handling primitive int, short and byte values. + */ + static class InlinePrimitiveIntegerSerializer implements InlineSerializer + { + // Implementations for InlineSerializer. + + @Override + public boolean canSerialize(ClassPool programClassPool, + GsonRuntimeSettings gsonRuntimeSettings) + { + return true; + } + + + @Override + public void serialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder ____, + GsonRuntimeSettings gsonRuntimeSettings) + { + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.THIS) + .getfield(programClass, programField); + ____.invokestatic(ClassConstants.NAME_JAVA_LANG_INTEGER, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_INT); + ____.invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_VALUE_NUMBER, + GsonClassConstants.METHOD_TYPE_VALUE_NUMBER) + .pop(); + } + } + + /** + * Serializer for handling String values. + */ + static class InlineStringSerializer implements InlineSerializer + { + // Implementations for InlineSerializer. + + @Override + public boolean canSerialize(ClassPool programClassPool, + GsonRuntimeSettings gsonRuntimeSettings) + { + return true; + } + + + @Override + public void serialize(ProgramClass programClass, + ProgramField programField, + CodeAttributeEditor codeAttributeEditor, + InstructionSequenceBuilder ____, + GsonRuntimeSettings gsonRuntimeSettings) + { + ____.aload(OptimizedClassConstants.ToJsonLocals.JSON_WRITER) + .aload(OptimizedClassConstants.ToJsonLocals.THIS) + .getfield(programClass, programField) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_VALUE_STRING, + GsonClassConstants.METHOD_TYPE_NAME_VALUE_STRING) + .pop(); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/LocalOrAnonymousClassChecker.java proguard-6.2.0/core/src/proguard/optimize/gson/LocalOrAnonymousClassChecker.java --- proguard-6.0.3/core/src/proguard/optimize/gson/LocalOrAnonymousClassChecker.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/LocalOrAnonymousClassChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.InnerClassesInfo; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; + +/** + * Checks whether a visited class is a local or anonymous inner class. + * + * @author Lars Vandenbergh + */ +class LocalOrAnonymousClassChecker +extends SimplifiedVisitor +implements ClassVisitor, + InnerClassesInfoVisitor +{ + private boolean localOrAnonymous; + + + public boolean isLocalOrAnonymous() + { + return localOrAnonymous; + } + + + // Implementations for ClassVisitor. + + @Override + public void visitAnyClass(Clazz clazz) {} + + + @Override + public void visitProgramClass(ProgramClass programClass) + { + localOrAnonymous = false; + programClass.attributesAccept(new AllInnerClassesInfoVisitor(this)); + } + + + // Implementations for InnerClassesInfoVisitor. + + @Override + public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) + { + if (innerClassesInfo.u2innerClassIndex == ((ProgramClass)clazz).u2thisClass) + { + localOrAnonymous = innerClassesInfo.u2outerClassIndex == 0 || + innerClassesInfo.u2innerNameIndex == 0; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/MarkedAnnotationDeleter.java proguard-6.2.0/core/src/proguard/optimize/gson/MarkedAnnotationDeleter.java --- proguard-6.0.3/core/src/proguard/optimize/gson/MarkedAnnotationDeleter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/MarkedAnnotationDeleter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,205 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.Attribute; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.util.SimplifiedVisitor; + + +/** + * This AttributeVisitor deletes annotations with the given object as + * visitorInfo on the attributes that it visits. + * If deleting an annotation results in the corresponding annotation attribute + * to be empty, that attribute will be deleted as well. + * + * @author Rob Coekaerts + */ +class MarkedAnnotationDeleter +extends SimplifiedVisitor +implements AttributeVisitor +{ + // A visitor info flag to indicate the annotation can be deleted. + private final Object mark; + + + /** + * Creates a new MarkedAnnotationDeleter. + * + * @param mark the visitor info used to recognize annotations that + * need to be deleted. + */ + public MarkedAnnotationDeleter(Object mark) + { + this.mark = mark; + } + + + // Implementations for AttributeVisitor. + + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, + Member member, + RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute) + { + cleanAnnotationsAttribute(clazz, + member, + runtimeVisibleAnnotationsAttribute, + ClassConstants.ATTR_RuntimeVisibleAnnotations); + } + + + @Override + public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, + Member member, + RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute) + { + cleanAnnotationsAttribute(clazz, + member, + runtimeInvisibleAnnotationsAttribute, + ClassConstants.ATTR_RuntimeInvisibleAnnotations); + } + + + @Override + public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, + Method method, + RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute) + { + cleanParameterAnnotationsAttribute(clazz, + method, + runtimeVisibleParameterAnnotationsAttribute, + ClassConstants.ATTR_RuntimeVisibleParameterAnnotations); + } + + + @Override + public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, + Method method, + RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute) + { + cleanParameterAnnotationsAttribute(clazz, + method, + runtimeInvisibleParameterAnnotationsAttribute, + ClassConstants.ATTR_RuntimeInvisibleParameterAnnotations); + } + + + @Override + public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, + Member member, + RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute) + { + cleanAnnotationsAttribute(clazz, + member, + runtimeVisibleTypeAnnotationsAttribute, + ClassConstants.ATTR_RuntimeVisibleTypeAnnotations); + } + + + @Override + public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, + Member member, + RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute) + { + cleanAnnotationsAttribute(clazz, + member, + runtimeInvisibleTypeAnnotationsAttribute, + ClassConstants.ATTR_RuntimeInvisibleTypeAnnotations); + } + + + // Utility methods + + + private void cleanAnnotationsAttribute(Clazz clazz, + Member member, + AnnotationsAttribute attribute, + String attributeName) + { + // Delete marked annotations. + AnnotationsAttributeEditor annotationsAttributeEditor = new AnnotationsAttributeEditor(attribute); + Annotation[] annotations = attribute.annotations; + for (int index = 0; index < attribute.u2annotationsCount; index++) + { + Annotation annotation = annotations[index]; + if (annotation.getVisitorInfo() == mark) + { + annotationsAttributeEditor.deleteAnnotation(index); + } + } + + // Delete attribute if no annotations are left. + if (attribute.u2annotationsCount == 0) + { + AttributesEditor attributesEditor = new AttributesEditor((ProgramClass) clazz, + (ProgramMember)member, + false); + attributesEditor.deleteAttribute(attributeName); + } + } + + + private void cleanParameterAnnotationsAttribute(Clazz clazz, + Member member, + ParameterAnnotationsAttribute attribute, + String attributeName) + { + // Delete marked annotations. + ParameterAnnotationsAttributeEditor annotationsAttributeEditor = + new ParameterAnnotationsAttributeEditor(attribute); + boolean allEmpty = true; + for (int parameterIndex = 0; parameterIndex < attribute.u1parametersCount; parameterIndex++) + { + int annotationsCount = attribute.u2parameterAnnotationsCount[parameterIndex]; + Annotation[] annotations = attribute.parameterAnnotations[parameterIndex]; + for (int annotationIndex = 0; annotationIndex < annotationsCount; annotationIndex++) + { + Annotation annotation = annotations[annotationIndex]; + if (annotation.getVisitorInfo() == mark) + { + annotationsAttributeEditor.deleteAnnotation(parameterIndex, annotationIndex); + } + } + if (attribute.u2parameterAnnotationsCount[parameterIndex] != 0) + { + allEmpty = false; + } + } + + // Delete attribute if all parameters have no annotations left. + if (allEmpty) + { + AttributesEditor attributesEditor = new AttributesEditor((ProgramClass) clazz, + (ProgramMember)member, + false); + attributesEditor.deleteAttribute(attributeName); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedClassConstants.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedClassConstants.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedClassConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedClassConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,146 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.util.ClassUtil; + +/** + * Constants used in the injected GSON optimization classes. + * + * @author Lars Vandenbergh + */ +public class OptimizedClassConstants +{ + // The class names contained in these strings will be mapped during + // obfuscation by -adaptclassstrings. + // We can't use .class.getName() for these template classes because it + // would indirectly load Gson library classes which are not on the runtime + // classpath of ProGuard. + public static final String NAME_GSON_UTIL = "proguard/optimize/gson/_GsonUtil"; + public static final String NAME_OPTIMIZED_JSON_READER = "proguard/optimize/gson/_OptimizedJsonReader"; + public static final String NAME_OPTIMIZED_JSON_READER_IMPL = "proguard/optimize/gson/_OptimizedJsonReaderImpl"; + public static final String NAME_OPTIMIZED_JSON_WRITER = "proguard/optimize/gson/_OptimizedJsonWriter"; + public static final String NAME_OPTIMIZED_JSON_WRITER_IMPL = "proguard/optimize/gson/_OptimizedJsonWriterImpl"; + public static final String NAME_OPTIMIZED_TYPE_ADAPTER = "proguard/optimize/gson/_OptimizedTypeAdapter"; + public static final String NAME_OPTIMIZED_TYPE_ADAPTER_FACTORY = "proguard/optimize/gson/_OptimizedTypeAdapterFactory"; + public static final String NAME_OPTIMIZED_TYPE_ADAPTER_IMPL = "proguard/optimize/gson/_OptimizedTypeAdapterImpl"; + + public static final String METHOD_NAME_INIT_NAMES_MAP = "a"; + public static final String METHOD_TYPE_INIT_NAMES_MAP = "()Ljava/util/Map;"; + public static final String METHOD_NAME_NEXT_FIELD_INDEX = "b"; + public static final String METHOD_TYPE_NEXT_FIELD_INDEX = "(Lcom/google/gson/stream/JsonReader;)I"; + public static final String METHOD_NAME_NEXT_VALUE_INDEX = "c"; + public static final String METHOD_TYPE_NEXT_VALUE_INDEX = "(Lcom/google/gson/stream/JsonReader;)I"; + + public static final String METHOD_NAME_INIT_NAMES = "a"; + public static final String METHOD_TYPE_INIT_NAMES = "()[Ljava/lang/String;"; + public static final String METHOD_NAME_NAME = "b"; + public static final String METHOD_TYPE_NAME = "(Lcom/google/gson/stream/JsonWriter;I)V"; + public static final String METHOD_NAME_VALUE = "c"; + public static final String METHOD_TYPE_VALUE = "(Lcom/google/gson/stream/JsonWriter;I)V"; + + public static final String FIELD_NAME_OPTIMIZED_JSON_READER_IMPL = "optimizedJsonReaderImpl"; + public static final String FIELD_TYPE_OPTIMIZED_JSON_READER_IMPL = ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_READER_IMPL); + public static final String FIELD_NAME_OPTIMIZED_JSON_WRITER_IMPL = "optimizedJsonWriterImpl"; + public static final String FIELD_TYPE_OPTIMIZED_JSON_WRITER_IMPL = ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_WRITER_IMPL); + public static final String METHOD_TYPE_INIT = "(Lcom/google/gson/Gson;" + + ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_READER) + + ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_WRITER) + ")V"; + public static final String METHOD_NAME_CREATE = "create"; + public static final String METHOD_TYPE_CREATE = "(Lcom/google/gson/Gson;Lcom/google/gson/reflect/TypeToken;)Lcom/google/gson/TypeAdapter;"; + + + public static final String TYPE_OPTIMIZED_TYPE_ADAPTER_IMPL = ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_TYPE_ADAPTER_IMPL); + public static final String FIELD_NAME_GSON = "gson"; + public static final String FIELD_TYPE_GSON = "Lcom/google/gson/Gson;"; + public static final String FIELD_NAME_OPTIMIZED_JSON_READER = "optimizedJsonReader"; + public static final String FIELD_TYPE_OPTIMIZED_JSON_READER = ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_READER); + public static final String FIELD_NAME_OPTIMIZED_JSON_WRITER = "optimizedJsonWriter"; + public static final String FIELD_TYPE_OPTIMIZED_JSON_WRITER = ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_WRITER); + public static final String METHOD_NAME_READ = "read"; + public static final String METHOD_NAME_WRITE = "write"; + + public static final String FIELD_NAME_EXCLUDER = "excluder"; + public static final String FIELD_TYPE_EXCLUDER = "Lcom/google/gson/internal/Excluder;"; + public static final String FIELD_NAME_REQUIRE_EXPOSE = "requireExpose"; + public static final String FIELD_TYPE_REQUIRE_EXPOSE = "Z"; + + public static final class ReadLocals + { + public static final int THIS = 0; + public static final int JSON_READER = 1; + public static final int VALUE = 2; + } + + public static final class WriteLocals + { + public static final int THIS = 0; + public static final int JSON_WRITER = 1; + public static final int VALUE = 2; + } + + + public static final String METHOD_NAME_GET_TYPE_ADAPTER_CLASS = "getTypeAdapter"; + public static final String METHOD_TYPE_GET_TYPE_ADAPTER_CLASS = "(Lcom/google/gson/Gson;Ljava/lang/Class;Ljava/lang/Object;)Lcom/google/gson/TypeAdapter;"; + public static final String METHOD_NAME_GET_TYPE_ADAPTER_TYPE_TOKEN = "getTypeAdapter"; + public static final String METHOD_TYPE_GET_TYPE_ADAPTER_TYPE_TOKEN = "(Lcom/google/gson/Gson;Lcom/google/gson/reflect/TypeToken;Ljava/lang/Object;)Lcom/google/gson/TypeAdapter;"; + public static final String METHOD_NAME_DUMP_TYPE_TOKEN_CACHE = "dumpTypeTokenCache"; + public static final String METHOD_TYPE_DUMP_TYPE_TOKEN_CACHE = "(Ljava/lang/String;Ljava/util/Map;)V"; + + public static final String METHOD_NAME_FROM_JSON = "fromJson$"; + public static final String METHOD_TYPE_FROM_JSON = "(Lcom/google/gson/Gson;Lcom/google/gson/stream/JsonReader;" + + ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_READER) + ")V"; + public static final String METHOD_NAME_FROM_JSON_FIELD = "fromJsonField$"; + public static final String METHOD_TYPE_FROM_JSON_FIELD = "(Lcom/google/gson/Gson;Lcom/google/gson/stream/JsonReader;I)V"; + + public static final class FromJsonLocals + { + public static final int THIS = 0; + public static final int GSON = 1; + public static final int JSON_READER = 2; + public static final int OPTIMIZED_JSON_READER = 3; + public static final int MAX_LOCALS = 3; + } + + public static final class FromJsonFieldLocals + { + public static final int THIS = 0; + public static final int GSON = 1; + public static final int JSON_READER = 2; + public static final int FIELD_INDEX = 3; + } + + public static final String METHOD_NAME_TO_JSON = "toJson$"; + public static final String METHOD_TYPE_TO_JSON = "(Lcom/google/gson/Gson;Lcom/google/gson/stream/JsonWriter;" + + ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_WRITER) + ")V"; + public static final String METHOD_NAME_TO_JSON_BODY = "toJsonBody$"; + public static final String METHOD_TYPE_TO_JSON_BODY = "(Lcom/google/gson/Gson;Lcom/google/gson/stream/JsonWriter;" + + ClassUtil.internalTypeFromClassName(NAME_OPTIMIZED_JSON_WRITER) + ")V"; + + public static final class ToJsonLocals + { + public static final int THIS = 0; + public static final int GSON = 1; + public static final int JSON_WRITER = 2; + public static final int OPTIMIZED_JSON_WRITER = 3; + } +} + diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonFieldCollector.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonFieldCollector.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonFieldCollector.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonFieldCollector.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,252 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +import java.util.*; + +/** + * This class and member visitor collects the classes and fields that can be + * involved in Json (de)serialization and register their Java to Json field + * name mapping in an OptimizedJsonInfo object + * + * @author Lars Vandenbergh + * @author Rob Coekaerts + */ +public class OptimizedJsonFieldCollector +extends SimplifiedVisitor +implements ClassVisitor, + MemberVisitor +{ + private final OptimizedJsonInfo optimizedJsonInfo; + private final Mode mode; + private OptimizedJsonInfo.ClassJsonInfo classJsonInfo; + + + /** + * Creates a new OptimizedJsonFieldCollector. + * + * @param optimizedJsonInfo contains information on which classes and fields + * need to optimized and how. + * @param mode whether serialization or deserialization is + * being done. + */ + public OptimizedJsonFieldCollector(OptimizedJsonInfo optimizedJsonInfo, + Mode mode) + { + this.optimizedJsonInfo = optimizedJsonInfo; + this.mode = mode; + } + + + // Implementations for ClassVisitor. + + @Override + public void visitProgramClass(ProgramClass programClass) + { + classJsonInfo = new OptimizedJsonInfo.ClassJsonInfo(); + optimizedJsonInfo.classJsonInfos.put(programClass.getName(), classJsonInfo); + optimizedJsonInfo.classIndices.put(programClass.getName(), null); + } + + + @Override + public void visitLibraryClass(LibraryClass libraryClass) {} + + + // Implementations for MemberVisitor. + + @Override + public void visitAnyMember(Clazz clazz, Member member) {} + + + @Override + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + OptimizedJsonInfo.ClassJsonInfo classJsonInfo = + optimizedJsonInfo.classJsonInfos.get(programClass.getName()); + + programField.attributesAccept(programClass, + new AllAnnotationVisitor( + new MultiAnnotationVisitor( + new AnnotationTypeFilter(GsonClassConstants.ANNOTATION_TYPE_SERIALIZED_NAME, + new SerializedNamesCollector(classJsonInfo)), + new AnnotationTypeFilter(GsonClassConstants.ANNOTATION_TYPE_EXPOSE, + new ExposedFieldsCollector(classJsonInfo, mode))))); + + + String fieldName = programField.getName(programClass); + if (classJsonInfo.javaToJsonFieldNames.get(fieldName) == null) + { + classJsonInfo.javaToJsonFieldNames.put(fieldName, new String[] { fieldName }); + optimizedJsonInfo.jsonFieldIndices.put(fieldName, null); + } + else + { + for (String jsonFieldName: classJsonInfo.javaToJsonFieldNames.get(fieldName)) + { + optimizedJsonInfo.jsonFieldIndices.put(jsonFieldName, null); + } + } + } + + + private static class ExposedFieldsCollector + extends SimplifiedVisitor + implements AnnotationVisitor, + ElementValueVisitor, + ConstantVisitor + { + private final OptimizedJsonInfo.ClassJsonInfo classJsonInfo; + private final Mode mode; + + public boolean exposeCurrentField; + + + public ExposedFieldsCollector(OptimizedJsonInfo.ClassJsonInfo classJsonInfo, Mode mode) + { + this.classJsonInfo = classJsonInfo; + this.mode = mode; + } + + + // Implementations for AnnotationVisitor + + @Override + public void visitAnnotation(Clazz clazz, Annotation annotation) {} + + + @Override + public void visitAnnotation(Clazz clazz, Field field, Annotation annotation) + { + exposeCurrentField = true; + annotation.elementValuesAccept(clazz, this); + if (exposeCurrentField) + { + classJsonInfo.exposedJavaFieldNames.add(field.getName(clazz)); + } + } + + + // Implementations for ElementValueVisitor + + @Override + public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) {} + + + @Override + public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) + { + if(constantElementValue.getMethodName(clazz).equals(mode.toString())) + { + clazz.constantPoolEntryAccept(constantElementValue.u2constantValueIndex, this); + } + } + + + @Override + public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) {} + + + // Implementations for ConstantVisitor + + @Override + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + @Override + public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) + { + if (integerConstant.u4value == 0) + { + exposeCurrentField = false; + } + } + } + + + private static class SerializedNamesCollector + extends SimplifiedVisitor + implements AnnotationVisitor, + ElementValueVisitor + { + private final OptimizedJsonInfo.ClassJsonInfo classJsonInfo; + private List currentJsonFieldNames; + + + public SerializedNamesCollector(OptimizedJsonInfo.ClassJsonInfo classJsonInfo) + { + this.classJsonInfo = classJsonInfo; + } + + + // Implementations for AnnotationVisitor + + @Override + public void visitAnnotation(Clazz clazz, Annotation annotation) {} + + + @Override + public void visitAnnotation(Clazz clazz, Field field, Annotation annotation) + { + currentJsonFieldNames = new ArrayList(); + + annotation.elementValuesAccept(clazz, this); + + String[] jsonNamesArray = currentJsonFieldNames.toArray(new String[0]); + classJsonInfo.javaToJsonFieldNames.put(field.getName(clazz), jsonNamesArray); + } + + + // Implementations for ElementValueVisitor + + @Override + public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) {} + + + @Override + public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) + { + currentJsonFieldNames.add(clazz.getString(constantElementValue.u2constantValueIndex)); + } + + + @Override + public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) + { + arrayElementValue.elementValuesAccept(clazz, annotation, this); + } + } + + + public enum Mode + { + serialize, + deserialize + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonFieldVisitor.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonFieldVisitor.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonFieldVisitor.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonFieldVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; + +/** + * This visitor searches the classes that it visits for fields that can be + * involved in Json (de)serialization and passes them on to the given member + * visitor. + * + * For convenience, the classes that are visited are also passed on to the + * given class visitor. + * + * @author Lars Vandenbergh + */ +public class OptimizedJsonFieldVisitor +extends SimplifiedVisitor +implements ClassVisitor, + MemberVisitor +{ + private final ClassVisitor classVisitor; + private final MemberVisitor memberVisitor; + + + /** + * Creates a new OptimizedJsonFieldVisitor. + * + * @param classVisitor the visitor to which (de)serialized classes are + * delegated to. + * @param memberVisitor the visitor to which (de)serialized fields + * are delegated to. + */ + public OptimizedJsonFieldVisitor(ClassVisitor classVisitor, + MemberVisitor memberVisitor) + { + this.classVisitor = classVisitor; + this.memberVisitor = memberVisitor; + } + + // Implementations for ClassVisitor. + + @Override + public void visitAnyClass(Clazz clazz) {} + + + @Override + public void visitProgramClass(ProgramClass programClass) + { + programClass.accept(classVisitor); + programClass.accept(new ClassAccessFilter(0, ClassConstants.ACC_ENUM, + new AllFieldVisitor( + new MemberAccessFilter(0, ClassConstants.ACC_TRANSIENT, + this)))); + + // For enums, only visit the enum constant fields. + programClass.accept(new ClassAccessFilter(ClassConstants.ACC_ENUM, 0, + new AllFieldVisitor( + new MemberAccessFilter(0, ClassConstants.ACC_TRANSIENT, + new MemberDescriptorFilter(ClassUtil.internalTypeFromClassName(programClass.getName()), + this))))); + } + + + // Implementations for MemberVisitor. + + @Override + public void visitAnyMember(Clazz clazz, Member member) {} + + + @Override + public void visitProgramField(ProgramClass programClass, ProgramField programField) + { + programField.accept(programClass, memberVisitor); + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonInfo.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonInfo.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import java.util.*; + +/** + * This class keeps track of which Java classes and fields can be involved in + * Json (de)serialization and stores their corresponding Json field names + * and internal indices. + * + * @author Lars Vandenbergh + * @author Rob Coekaerts + */ +public class OptimizedJsonInfo +{ + /** + * Maps the class name to a unique, contiguous index. + * This index is used to generate unique suffixes for the generated toJson + * and fromJson methods. + */ + public Map classIndices = new HashMap(); + + /** + * Maps the json field name to a unique, contiguous index. + * This index is used to map Json field names to indices and backwards + * in the _OptimizedJsonReader and _OptimizedJsonWriter. + */ + public Map jsonFieldIndices = new HashMap(); + + /** + * Maps the class name to a ClassJsonInfo. The ClassJsonInfo contains the + * names of all the exposed Java fields and their corresponding Json field + * name(s). + */ + public Map classJsonInfos = new HashMap(); + + + /** + * Assigns indices to all registered classes and fields. + * The generated indices will be contiguous and starting from 0, both + * for classes and fields. + */ + public void assignIndices() + { + assignIndices(classIndices); + assignIndices(jsonFieldIndices); + } + + private void assignIndices(Map indexMap) + { + int index = 0; + for (String fieldName : indexMap.keySet()) + { + indexMap.put(fieldName, index++); + } + } + + public static class ClassJsonInfo + { + /** + * Maps the Java field name to all of its corresponding Json field names. + * The first name in the array is the primary name that is used for + * writing to Json. The remaining names are alternatives that are + * also accepted when reading from Json. + */ + public Map javaToJsonFieldNames = new HashMap(); + + /** + * Contains the names of all (and only those) Java fields that are + * exposed. + */ + public Set exposedJavaFieldNames = new HashSet(); + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonReaderImplInitializer.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonReaderImplInitializer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonReaderImplInitializer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonReaderImplInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,115 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.util.SimplifiedVisitor; + +import java.util.Map; + +/** + * This code attribute visitor implements the static initializer of + * _OptimizedJsonReaderImpl so that the data structure is initialized + * with the correct mapping between Json field names and internal + * indices. + * + * @author Lars Vandenbergh + */ +public class OptimizedJsonReaderImplInitializer +extends SimplifiedVisitor +implements AttributeVisitor +{ + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final CodeAttributeEditor codeAttributeEditor; + private final OptimizedJsonInfo deserializationInfo; + + + /** + * Creates a new OptimizedJsonReaderImplInitializer. + * + * @param programClassPool the program class pool used for looking up + * program class references. + * @param libraryClassPool the library class pool used for looking up + * library class references. + * @param codeAttributeEditor the code attribute editor used for editing + * the code attribute of the static initializer. + * @param deserializationInfo contains information on which classes and + * fields to deserialize and how. + */ + public OptimizedJsonReaderImplInitializer(ClassPool programClassPool, + ClassPool libraryClassPool, + CodeAttributeEditor codeAttributeEditor, + OptimizedJsonInfo deserializationInfo) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.codeAttributeEditor = codeAttributeEditor; + this.deserializationInfo = deserializationInfo; + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + + InstructionSequenceBuilder ____ = + new InstructionSequenceBuilder((ProgramClass)clazz, + programClassPool, + libraryClassPool); + + ____.new_(ClassConstants.NAME_JAVA_UTIL_HASH_MAP, libraryClassPool.getClass(ClassConstants.NAME_JAVA_UTIL_HASH_MAP)) + .dup() + .invokespecial(ClassConstants.NAME_JAVA_UTIL_HASH_MAP, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT); + + for (Map.Entry jsonFieldIndicesEntry : deserializationInfo.jsonFieldIndices.entrySet()) + { + ____.dup() + .ldc(jsonFieldIndicesEntry.getKey()) + .ldc(jsonFieldIndicesEntry.getValue().intValue()) + .invokestatic(ClassConstants.NAME_JAVA_LANG_INTEGER, + ClassConstants.METHOD_NAME_VALUE_OF, + ClassConstants.METHOD_TYPE_VALUE_OF_INT) + .invokevirtual(ClassConstants.NAME_JAVA_UTIL_HASH_MAP, + ClassConstants.METHOD_NAME_MAP_PUT, + ClassConstants.METHOD_TYPE_MAP_PUT) + .pop(); + } + + // We replace the instruction that loads null on the stack with the + // initialization code and leave the return instruction that comes + // right after it in place. + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonReaderImpl.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonReaderImpl.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonReaderImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonReaderImpl.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.stream.*; + +import java.io.IOException; +import java.util.*; + +/** + * This class is a template for an _OptimizedJsonReader implementation. + * The data structure that contains the mapping between Json field names + * and internal indices is empty and needs to be initialized using injected + * byte code. + * + * @author Lars Vandenbergh + */ +public class _OptimizedJsonReaderImpl +implements _OptimizedJsonReader +{ + /* + * The original name of this field is "names". + * + * The name of this field has already been obfuscated because it is part + * of an injected class. + * + * When renaming this field, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + */ + private static final Map a = a(); + + + /* + * Initializes the data structure containing the mapping between Json field + * names and internal indices. + * + * The original name of this method is "initNames". + * + * The name of this method has already been obfuscated because it is part + * of an injected class. + * + * When renaming this method, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + */ + private static Map a() + { + return null; + } + + // Implementations for _OptimizedJsonReader. + + @Override + public int b(JsonReader jsonReader) throws IOException + { + String name = jsonReader.nextName(); + Integer fieldIndex = a.get(name); + return fieldIndex == null ? -1 : fieldIndex; + } + + @Override + public int c(JsonReader jsonReader) throws IOException + { + String value = jsonReader.nextString(); + Integer valueIndex = a.get(value); + return valueIndex == null ? -1 : valueIndex; + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonReader.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonReader.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonReader.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.stream.*; + +import java.io.IOException; + +/** + * Interface for reading Json fields and values using an internal index. + * This allows injecting optimized Java code that reads and interprets Json + * without referring to Json field names and values using plain Strings. + * + * @author Lars Vandenbergh + */ +public interface _OptimizedJsonReader +{ + /** + * Reads the internal index of the next Json field from the given Json + * reader. + * + * The original name of this method is "nextFieldIndex". + * + * The name of this method has already been obfuscated because it is part + * of an injected class. + * + * When renaming this field, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + * + * @param jsonReader the Json reader to read from. + * @return the internal index of the read field value. + * @throws IOException if the reading failed. + */ + int b(JsonReader jsonReader) throws IOException; + + /** + * Reads the internal index of the next Json value from the given Json + * reader. + * + * The original name of this method is "nextValueIndex". + * + * The name of this method has already been obfuscated because it is part + * of an injected class. + * + * When renaming this method, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + * + * @param jsonReader the Json reader to read from. + * @return the internal index of the read field value. + * @throws IOException if the reading failed. + */ + int c(JsonReader jsonReader) throws IOException; +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonWriterImplInitializer.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonWriterImplInitializer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedJsonWriterImplInitializer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedJsonWriterImplInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.AttributeVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.util.SimplifiedVisitor; + +import java.util.Map; + +/** + * This code attribute visitor implements the static initializer of + * _OptimizedJsonWriterImpl so that the data structure is initialized + * with the correct mapping between internal indices and Json field names. + * + * @author Lars Vandenbergh + */ +public class OptimizedJsonWriterImplInitializer +extends SimplifiedVisitor +implements AttributeVisitor +{ + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final CodeAttributeEditor codeAttributeEditor; + private final OptimizedJsonInfo serializationInfo; + + + /** + * Creates a new OptimizedJsonWriterImplInitializer. + * + * @param programClassPool the program class pool used for looking up + * program class references. + * @param libraryClassPool the library class pool used for looking up + * library class references. + * @param codeAttributeEditor the code attribute editor used for editing + * the code attribute of the static initializer. + * @param serializationInfo contains information on which classes and + * fields to serialize and how. + */ + public OptimizedJsonWriterImplInitializer(ClassPool programClassPool, + ClassPool libraryClassPool, + CodeAttributeEditor codeAttributeEditor, + OptimizedJsonInfo serializationInfo) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.codeAttributeEditor = codeAttributeEditor; + this.serializationInfo = serializationInfo; + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + + InstructionSequenceBuilder ____ = + new InstructionSequenceBuilder((ProgramClass)clazz, + programClassPool, + libraryClassPool); + + Map fieldIndices = serializationInfo.jsonFieldIndices; + + ____.ldc(fieldIndices.size()) + .anewarray(ClassConstants.NAME_JAVA_LANG_STRING, + libraryClassPool.getClass(ClassConstants.NAME_JAVA_LANG_STRING)); + + for (Map.Entry fieldIndexEntry : fieldIndices.entrySet()) + { + ____.dup() + .ldc(fieldIndexEntry.getValue().intValue()) + .ldc(fieldIndexEntry.getKey()) + .aastore(); + } + + // We replace the instruction that loads null on the stack with the + // initialization code and leave the return instruction that comes + // right after it in place. + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonWriterImpl.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonWriterImpl.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonWriterImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonWriterImpl.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +/** + * This class is a template for an _OptimizedJsonWriter implementation. + * The data structure that contains the mapping between internal indices + * and Json field names is empty and needs to be initialized using injected + * byte code. + * + * @author Lars Vandenbergh + */ +public class _OptimizedJsonWriterImpl +implements _OptimizedJsonWriter +{ + /* + * The original name of this field is "names". + * + * The name of this field has already been obfuscated because it is part + * of an injected class. + * + * When renaming this field, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + */ + private static final String[] a = a(); + + + /* + * Initializes the data structure containing the mapping between internal + * indices and Json field names. + * + * The original name of this method is "initNames". + * + * The name of this method has already been obfuscated because it is part + * of an injected class. + * + * When renaming this method, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + */ + private static String[] a() + { + return null; + } + + + // Implementations for _OptimizedJsonWriter. + + @Override + public void b(JsonWriter jsonWriter, int nameIndex) throws IOException + { + jsonWriter.name(a[nameIndex]); + } + + @Override + public void c(JsonWriter jsonWriter, int valueIndex) throws IOException + { + jsonWriter.value(a[valueIndex]); + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonWriter.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonWriter.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedJsonWriter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedJsonWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +/* + * Interface for writing Json fields and values using an internal index. + * This allows injecting optimized Java code that writes out Json without + * referring to Json field names and values using plain Strings. + * + * @author Lars Vandenbergh + */ +public interface _OptimizedJsonWriter +{ + /** + * Writes the field name with the given internal index to the given Json writer. + * + * The original name of this method is "name". + * + * The name of this field has already been obfuscated because it is part + * of an injected class. + * + * When renaming this field, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + * + * @param jsonWriter the Json writer to write to. + * @param nameIndex the internal index of the field name. + * @throws IOException if the writing failed. + */ + void b(JsonWriter jsonWriter, int nameIndex) throws IOException; + + /** + * Writes the field value with the given internal index to the given Json writer. + * + * The original name of this method is "value". + * + * The name of this method has already been obfuscated because it is part + * of an injected class. + * + * When renaming this method, the corresponding constant in + * OptimizedClassConstants needs to be updated accordingly. + * + * @param jsonWriter the Json writer to write to. + * @param valueIndex the internal index of the field value. + * @throws IOException if the writing failed. + */ + void c(JsonWriter jsonWriter, int valueIndex) throws IOException; +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedTypeAdapterAdder.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedTypeAdapterAdder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedTypeAdapterAdder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedTypeAdapterAdder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.editor.CodeAttributeEditor; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; +import proguard.io.*; +import proguard.util.MultiValueMap; + +import java.io.IOException; +import java.util.Map; + +import static proguard.optimize.gson.OptimizedClassConstants.NAME_OPTIMIZED_TYPE_ADAPTER_IMPL; + +/** + * This ClassVisitor visits domain classes that can be involved in a GSON + * (de)serialization and injects an optimized TypeAdapter for each of them. + * + * @author Lars Vandenbergh + */ +public class OptimizedTypeAdapterAdder implements ClassVisitor +{ + private static final boolean DEBUG = false; + + private final ClassPool programClassPool; + private final ClassPool libraryClassPool; + private final CodeAttributeEditor codeAttributeEditor; + private final OptimizedJsonInfo serializationInfo; + private final OptimizedJsonInfo deserializationInfo; + private final MultiValueMap injectedClassNameMap; + private final Map typeAdapterRegistry; + private final ClassPool instanceCreatorClassPool; + + + /** + * Creates a new OptimizedTypeAdapterAdder. + * + * @param programClassPool the program class pool used for looking + * up references to program classes. + * @param libraryClassPool the library class pool used for looking + * up references to library classes. + * @param codeAttributeEditor the code attribute editor used for + * implementing the added type adapters. + * @param serializationInfo contains information on which classes + * and fields to serialize and how. + * @param deserializationInfo contains information on which classes + * and fields to deserialize and how. + * @param injectedClassNameMap map to which the names of new type + * adapter classes are added. + * @param typeAdapterRegistry the registry to which the corresponding + * type adapter class name is added for a + * given domain class name. + * @param instanceCreatorClassPool class pool that contains the domain + * classes for which an InstanceCreator + * is registered. + */ + public OptimizedTypeAdapterAdder(ClassPool programClassPool, + ClassPool libraryClassPool, + CodeAttributeEditor codeAttributeEditor, + OptimizedJsonInfo serializationInfo, + OptimizedJsonInfo deserializationInfo, + MultiValueMap injectedClassNameMap, + Map typeAdapterRegistry, + ClassPool instanceCreatorClassPool) + { + this.programClassPool = programClassPool; + this.libraryClassPool = libraryClassPool; + this.codeAttributeEditor = codeAttributeEditor; + this.serializationInfo = serializationInfo; + this.deserializationInfo = deserializationInfo; + this.injectedClassNameMap = injectedClassNameMap; + this.typeAdapterRegistry = typeAdapterRegistry; + this.instanceCreatorClassPool = instanceCreatorClassPool; + } + + + // Implementations for ClassVisitor. + + @Override + public void visitProgramClass(ProgramClass programClass) + { + // Derive class name for optimized type adapter from the name of the + // domain class. + String externalClassName = ClassUtil.externalClassName(programClass.getName()); + String packageName = ClassUtil.externalPackageName(externalClassName); + String shortClassName = ClassUtil.externalShortClassName(externalClassName); + String externalTypeAdapterClassName = packageName + JavaConstants.PACKAGE_SEPARATOR + + "Optimized" + shortClassName + "TypeAdapter"; + String typeAdapterClassName = ClassUtil.internalClassName(externalTypeAdapterClassName); + + + if (programClassPool.getClass(typeAdapterClassName) == null) + { + if (DEBUG) + { + System.out.println("OptimizedTypeAdapterAdder: injecting " + + typeAdapterClassName); + } + + ClassReader templateClassReader = + new ClassReader(false, false, false, null, + new OptimizedTypeAdapterInitializer( + typeAdapterClassName, + programClass, + codeAttributeEditor, + serializationInfo, + deserializationInfo, + instanceCreatorClassPool, + new MultiClassVisitor( + new ClassPresenceFilter(programClassPool, null, + new ClassPoolFiller(programClassPool)), + new ClassReferenceInitializer(programClassPool, libraryClassPool), + new ClassSubHierarchyInitializer()))); + + try + { + String dataEntryName = getDataEntryName(NAME_OPTIMIZED_TYPE_ADAPTER_IMPL); + templateClassReader.read(new ClassPathDataEntry(dataEntryName)); + injectedClassNameMap.put(programClass.getName(), typeAdapterClassName); + typeAdapterRegistry.put(programClass.getName(), typeAdapterClassName); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + } + + + @Override + public void visitLibraryClass(LibraryClass libraryClass) {} + + // Utility methods. + + private static String getDataEntryName(String internalClassName) + { + // This is mostly done to make sure the internal class name gets + // adapted properly during obfuscation. + return internalClassName + ".class"; + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedTypeAdapterFactoryInitializer.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedTypeAdapterFactoryInitializer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedTypeAdapterFactoryInitializer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedTypeAdapterFactoryInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,192 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.editor.*; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.*; + +import java.lang.reflect.Modifier; +import java.util.Map; + +/** + * This visitor implements the getType() method of the injected + * _OptimizedTypeAdapterFactory. + * + * @author Lars Vandenbergh + */ +public class OptimizedTypeAdapterFactoryInitializer +extends SimplifiedVisitor +implements InstructionVisitor +{ + private final ClassPool programClassPool; + private final CodeAttributeEditor codeAttributeEditor; + private final Map typeAdapterRegistry; + private final GsonRuntimeSettings gsonRuntimeSettings; + + + /** + * Creates a new OptimizedTypeAdapterFactoryInitializer. + * + * @param programClassPool the program class pool used for looking up + * references to program classes. + * @param codeAttributeEditor the code attribute editor used for editing + * the code attribute of the getType() method. + * @param typeAdapterRegistry contains the mapping between domain class + * names and their corresponding type adapter + * class name. + * @param gsonRuntimeSettings keeps track of all GsonBuilder invocations. + */ + public OptimizedTypeAdapterFactoryInitializer(ClassPool programClassPool, + CodeAttributeEditor codeAttributeEditor, + Map typeAdapterRegistry, + GsonRuntimeSettings gsonRuntimeSettings) + { + this.programClassPool = programClassPool; + this.codeAttributeEditor = codeAttributeEditor; + this.typeAdapterRegistry = typeAdapterRegistry; + this.gsonRuntimeSettings = gsonRuntimeSettings; + } + + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + if (method.getName(clazz).equals(OptimizedClassConstants.METHOD_NAME_CREATE) && + method.getDescriptor(clazz).equals(OptimizedClassConstants.METHOD_TYPE_CREATE) && + instruction.actualOpcode() == InstructionConstants.OP_ACONST_NULL) + { + InstructionSequenceBuilder ____ = + new InstructionSequenceBuilder((ProgramClass)clazz); + CodeAttributeEditor.Label end = codeAttributeEditor.label(); + + // Don't use optimized type adapter when an unsupported property is + // enabled during the construction of the Gson object. + if (gsonRuntimeSettings.setFieldNamingPolicy || + gsonRuntimeSettings.setFieldNamingStrategy) + { + ____.aload_1() // gson argument + .getfield(GsonClassConstants.NAME_GSON, + GsonClassConstants.FIELD_NAME_FIELD_NAMING_STRATEGY, + GsonClassConstants.FIELD_TYPE_FIELD_NAMING_STRATEGY) + .getstatic(GsonClassConstants.NAME_FIELD_NAMING_POLICY, + GsonClassConstants.FIELD_NAME_IDENTITY, + GsonClassConstants.FIELD_TYPE_IDENTITY) + .ifacmpne(end.offset()); + } + if (gsonRuntimeSettings.excludeFieldsWithModifiers) + { + ____.aload_1() // gson argument + .getfield(GsonClassConstants.NAME_GSON, + GsonClassConstants.FIELD_NAME_EXCLUDER, + GsonClassConstants.FIELD_TYPE_EXCLUDER) + .getfield(GsonClassConstants.NAME_EXCLUDER, + GsonClassConstants.FIELD_NAME_MODIFIERS, + GsonClassConstants.FIELD_TYPE_MODIFIERS) + .ldc(Modifier.STATIC | Modifier.TRANSIENT) + .ificmpne(end.offset()); + } + if (gsonRuntimeSettings.setExclusionStrategies || + gsonRuntimeSettings.addSerializationExclusionStrategy || + gsonRuntimeSettings.addDeserializationExclusionStrategy) + { + ____.aload_1() // gson argument + .getfield(GsonClassConstants.NAME_GSON, + GsonClassConstants.FIELD_NAME_EXCLUDER, + GsonClassConstants.FIELD_TYPE_EXCLUDER) + .getfield(GsonClassConstants.NAME_EXCLUDER, + GsonClassConstants.FIELD_NAME_SERIALIZATION_STRATEGIES, + GsonClassConstants.FIELD_TYPE_SERIALIZATION_STRATEGIES) + .invokevirtual(ClassConstants.NAME_JAVA_UTIL_LIST, + ClassConstants.METHOD_NAME_IS_EMPTY, + ClassConstants.METHOD_TYPE_IS_EMPTY) + .ifeq(end.offset()); + ____.aload_1() // gson argument + .getfield(GsonClassConstants.NAME_GSON, + GsonClassConstants.FIELD_NAME_EXCLUDER, + GsonClassConstants.FIELD_TYPE_EXCLUDER) + .getfield(GsonClassConstants.NAME_EXCLUDER, + GsonClassConstants.FIELD_NAME_DESERIALIZATION_STRATEGIES, + GsonClassConstants.FIELD_TYPE_DESERIALIZATION_STRATEGIES) + .invokevirtual(ClassConstants.NAME_JAVA_UTIL_LIST, + ClassConstants.METHOD_NAME_IS_EMPTY, + ClassConstants.METHOD_TYPE_IS_EMPTY) + .ifeq(end.offset()); + } + if (gsonRuntimeSettings.setVersion) + { + ____.aload_1() // gson argument + .getfield(GsonClassConstants.NAME_GSON, + GsonClassConstants.FIELD_NAME_EXCLUDER, + GsonClassConstants.FIELD_TYPE_EXCLUDER) + .getfield(GsonClassConstants.NAME_EXCLUDER, + GsonClassConstants.FIELD_NAME_VERSION, + GsonClassConstants.FIELD_TYPE_VERSION) + .ldc2_w(-1d) + .dcmpg() + .ifne(end.offset()); + } + + for (Map.Entry typeAdapterRegistryEntry : typeAdapterRegistry.entrySet()) + { + String objectType = typeAdapterRegistryEntry.getKey(); + String adapterType = typeAdapterRegistryEntry.getValue(); + Clazz objectClazz = programClassPool.getClass(objectType); + + CodeAttributeEditor.Label elseif = codeAttributeEditor.label(); + ____.aload_2() // type argument + .invokevirtual(GsonClassConstants.NAME_TYPE_TOKEN, + GsonClassConstants.METHOD_NAME_GET_RAW_TYPE, + GsonClassConstants.METHOD_TYPE_GET_RAW_TYPE) + .ldc(objectClazz) + .ifacmpne(elseif.offset()) + .new_(adapterType) + .dup() + .aload_1() // gson argument + .getstatic(clazz.getName(), + OptimizedClassConstants.FIELD_NAME_OPTIMIZED_JSON_READER_IMPL, + OptimizedClassConstants.FIELD_TYPE_OPTIMIZED_JSON_READER_IMPL) + .getstatic(clazz.getName(), + OptimizedClassConstants.FIELD_NAME_OPTIMIZED_JSON_WRITER_IMPL, + OptimizedClassConstants.FIELD_TYPE_OPTIMIZED_JSON_WRITER_IMPL) + .invokespecial(adapterType, + ClassConstants.METHOD_NAME_INIT, + OptimizedClassConstants.METHOD_TYPE_INIT) + .areturn() + .label(elseif); + } + + ____.label(end) + .aconst_null(); + + codeAttributeEditor.replaceInstruction(offset,____.instructions()); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedTypeAdapterFactory.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedTypeAdapterFactory.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedTypeAdapterFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedTypeAdapterFactory.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; + +/** + * Template class for the optimized type adapter factory that deals with all + * optimized GSON domain classes. + * + * The implementation of the create() method needs to be replaced with + * injected byte code that handles the specific domain classes and returns + * the appropriate optimized type adapter. + * + * @author Lars Vandenbergh + */ +public class _OptimizedTypeAdapterFactory implements TypeAdapterFactory +{ + private static final _OptimizedJsonReaderImpl optimizedJsonReaderImpl = new _OptimizedJsonReaderImpl(); + private static final _OptimizedJsonWriterImpl optimizedJsonWriterImpl = new _OptimizedJsonWriterImpl(); + + + // Implementations for TypeAdapterFactory. + @Override + public TypeAdapter create(Gson gson, TypeToken type) + { + return null; + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedTypeAdapterImpl.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedTypeAdapterImpl.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedTypeAdapterImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedTypeAdapterImpl.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import com.google.gson.*; +import com.google.gson.stream.*; + +import java.io.IOException; + +/** + * Template class for an optimized GSON type adapter. + * + * The implementation of the write() and read() methods need to be replaced + * with injected byte code that invokes the generated toJson$xxx() and + * fromJson$xxx() methods on the appropriate domain class. + */ +public class _OptimizedTypeAdapterImpl +extends TypeAdapter +implements _OptimizedTypeAdapter +{ + private Gson gson; + private _OptimizedJsonReader optimizedJsonReader; + private _OptimizedJsonWriter optimizedJsonWriter; + + + /** + * Creates a new _OptimizedTypeAdapterImpl. + * + * @param gson the Gson context. + * @param optimizedJsonReader the optimized reader used to read Json. + * @param optimizedJsonWriter the optimized writer used to write Json. + */ + public _OptimizedTypeAdapterImpl(Gson gson, _OptimizedJsonReader optimizedJsonReader, _OptimizedJsonWriter optimizedJsonWriter) + { + this.gson = gson; + this.optimizedJsonReader = optimizedJsonReader; + this.optimizedJsonWriter = optimizedJsonWriter; + } + + + // Implementations for TypeAdapter. + + @Override + public void write(JsonWriter writer, Object value) throws IOException + { + } + + @Override + public Object read(JsonReader reader) throws IOException + { + return null; + } +} \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedTypeAdapterInitializer.java proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedTypeAdapterInitializer.java --- proguard-6.0.3/core/src/proguard/optimize/gson/OptimizedTypeAdapterInitializer.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/OptimizedTypeAdapterInitializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,552 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.editor.*; +import proguard.classfile.editor.CodeAttributeEditor.Label; +import proguard.classfile.util.*; +import proguard.classfile.visitor.*; + +import java.util.*; + +/** + * This class visitor transforms the template _OptimizedTypeAdapter into a full + * implementation of a GSON TypeAdapter for a specific domain class. + * + * The read() and write() methods will be implemented appropriately and will + * delegate to the toJson$xxx() and fromJson$xxx() methods that are injected + * into the domain classes. + * + * The visited class will be renamed, e.g. if the domain class for which the + * TypeAdapter is meant to be used is called DomainObject, the class name will + * be OptimizedDomainObjectTypeAdapter. + * + * @author Lars Vandenbergh + */ +public class OptimizedTypeAdapterInitializer +extends SimplifiedVisitor +implements ClassVisitor +{ + private final String typeAdapterClassName; + private final String objectClassName; + private final ProgramClass objectProgramClass; + private final CodeAttributeEditor codeAttributeEditor; + private final OptimizedJsonInfo serializationIndexMap; + private final OptimizedJsonInfo deserializationIndexMap; + private final ClassPool instanceCreatorClasses; + private final ClassVisitor classVisitor; + + + /** + * Creates a new OptimizedTypeAdapterInitializer. + * + * @param typeAdapterClassName the class name of the optimized type + * adapter. + * @param objectProgramClass the class name of the domain class for + * which the type adapter is meant. + * @param codeAttributeEditor the code attribute editor used to edit + * the code attribute of the read() and + * write() methods. + * @param serializationInfo contains information on which classes + * and fields to serialize and how. + * @param deserializationInfo contains information on which classes + * and fields to deserialize and how. + * @param instanceCreatorClasses class pool that contains all domain + * classes for which an InstanceCreator + * is registered. + * @param classVisitor visitor to which all implemented type + * adapters are delegated. + */ + public OptimizedTypeAdapterInitializer(String typeAdapterClassName, + ProgramClass objectProgramClass, + CodeAttributeEditor codeAttributeEditor, + OptimizedJsonInfo serializationInfo, + OptimizedJsonInfo deserializationInfo, + ClassPool instanceCreatorClasses, + ClassVisitor classVisitor) + { + this.typeAdapterClassName = typeAdapterClassName; + this.objectClassName = ClassUtil.internalClassName(objectProgramClass.getName()); + this.objectProgramClass = objectProgramClass; + this.codeAttributeEditor = codeAttributeEditor; + this.serializationIndexMap = serializationInfo; + this.deserializationIndexMap = deserializationInfo; + this.instanceCreatorClasses = instanceCreatorClasses; + this.classVisitor = classVisitor; + } + + + // Implementations for ClassVisitor. + + @Override + public void visitAnyClass(Clazz clazz) {} + + + @Override + public void visitProgramClass(ProgramClass programClass) + { + // Rename template class to specific type adapter class name. + programClass.thisClassConstantAccept(new TypeAdapterRenamer()); + programClass.methodsAccept( + new AllAttributeVisitor( + new AllAttributeVisitor( + new LocalVariableTypeRenamer()))); + + boolean isEnumAdapter = (objectProgramClass.getAccessFlags() & ClassConstants.ACC_ENUM) != 0; + + if (isEnumAdapter) + { + // Make sure the enum is accessible from the type adapter. + objectProgramClass.u2accessFlags &= ~ClassConstants.ACC_PRIVATE; + objectProgramClass.u2accessFlags |= ClassConstants.ACC_PUBLIC; + } + + AttributeVisitor readImplementer = isEnumAdapter ? new EnumReadImplementer(): + new ReadImplementer(); + AttributeVisitor writeImplementer = isEnumAdapter ? new EnumWriteImplementer(): + new WriteImplementer(); + + if (deserializationIndexMap.classIndices.get(objectClassName) != null) + { + programClass.methodsAccept(new MemberNameFilter(OptimizedClassConstants.METHOD_NAME_READ, + new AllAttributeVisitor( + readImplementer))); + } + if (serializationIndexMap.classIndices.get(objectClassName) != null) + { + programClass.methodsAccept(new MemberNameFilter(OptimizedClassConstants.METHOD_NAME_WRITE, + new AllAttributeVisitor( + writeImplementer))); + } + + // Pass on to class visitor. + classVisitor.visitProgramClass(programClass); + } + + + private class TypeAdapterRenamer + extends SimplifiedVisitor + implements ConstantVisitor + { + + // Implementations for ConstantVisitor. + + @Override + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + @Override + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + classConstant.u2nameIndex = new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(typeAdapterClassName); + } + } + + + private class LocalVariableTypeRenamer + extends SimplifiedVisitor + implements AttributeVisitor, + LocalVariableInfoVisitor + { + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) + { + localVariableTableAttribute.localVariablesAccept(clazz,method,codeAttribute,this); + } + + // Implementations for LocalVariableInfoVisitor. + + + @Override + public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) + { + String descriptor = localVariableInfo.getDescriptor(clazz); + + if (descriptor.equals(OptimizedClassConstants.TYPE_OPTIMIZED_TYPE_ADAPTER_IMPL)) + { + localVariableInfo.u2descriptorIndex = new ConstantPoolEditor((ProgramClass)clazz).addUtf8Constant(ClassUtil.internalTypeFromClassName(typeAdapterClassName)); + } + } + } + + + /** + * Visits the code attribute of the the read() method of the TypeAdapter and + * provides it with a proper implementation for enum types. + */ + private class EnumReadImplementer + extends SimplifiedVisitor + implements AttributeVisitor + { + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + InstructionSequenceBuilder ____ = new InstructionSequenceBuilder((ProgramClass)clazz); + + // Deserialization + Map javaToJsonValueNames = deserializationIndexMap.classJsonInfos.get(objectClassName).javaToJsonFieldNames; + Map jsonFieldIndices = deserializationIndexMap.jsonFieldIndices; + + List switchCases = new ArrayList(); + + for (String javaValueName : javaToJsonValueNames.keySet()) + { + for (String jsonValueName : javaToJsonValueNames.get(javaValueName)) + { + switchCases.add(new SwitchCase(javaValueName, + codeAttributeEditor.label(), + jsonFieldIndices.get(jsonValueName))); + } + } + + Collections.sort(switchCases); + + int[] cases = new int[switchCases.size()]; + int[] jumpOffsets = new int[switchCases.size()]; + + for (int index = 0; index < switchCases.size(); index++) + { + cases[index] = switchCases.get(index).stringIndex; + jumpOffsets[index] = switchCases.get(index).label.offset(); + } + + CodeAttributeEditor.Label defaultCase = codeAttributeEditor.label(); + + ____.aload(OptimizedClassConstants.ReadLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_OPTIMIZED_JSON_READER, + OptimizedClassConstants.FIELD_TYPE_OPTIMIZED_JSON_READER) + .aload(OptimizedClassConstants.ReadLocals.JSON_READER) + .invokevirtual(OptimizedClassConstants.NAME_OPTIMIZED_JSON_READER, + OptimizedClassConstants.METHOD_NAME_NEXT_VALUE_INDEX, + OptimizedClassConstants.METHOD_TYPE_NEXT_VALUE_INDEX); + + ____.lookupswitch(defaultCase.offset(), + cases, + jumpOffsets); + + for (int index = 0; index < switchCases.size(); index++) + { + ____.label(switchCases.get(index).label) + .getstatic(objectClassName, + switchCases.get(index).enumConstant, + ClassUtil.internalTypeFromClassName(objectClassName)) + .areturn(); + } + + ____.label(defaultCase) + .aconst_null() + .areturn(); + + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + } + + + private static class SwitchCase implements Comparable + { + private String enumConstant; + private Label label; + private int stringIndex; + + public SwitchCase(String enumConstant, + Label label, + int stringIndex) + { + this.enumConstant = enumConstant; + this.label = label; + this.stringIndex = stringIndex; + } + + @Override + public int compareTo(SwitchCase switchCase) + { + return this.stringIndex - switchCase.stringIndex; + } + } + + + /** + * Visits the code attribute of the the read() method of the TypeAdapter and + * provides it with a proper implementation for non-enum types. + */ + private class ReadImplementer + extends SimplifiedVisitor + implements AttributeVisitor + { + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + InstructionSequenceBuilder ____ = + new InstructionSequenceBuilder((ProgramClass)clazz); + + Integer classIndex = deserializationIndexMap.classIndices.get(objectClassName); + String methodNameFromJson = OptimizedClassConstants.METHOD_NAME_FROM_JSON + classIndex; + + CodeAttributeEditor.Label nonNull = codeAttributeEditor.label(); + + // Peek the next value and check if it is null. + ____.aload(OptimizedClassConstants.ReadLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_PEEK, + GsonClassConstants.METHOD_TYPE_PEEK); + ____.getstatic(GsonClassConstants.NAME_JSON_TOKEN, + GsonClassConstants.FIELD_NAME_NULL, + GsonClassConstants.FIELD_TYPE_NULL) + .ifacmpne(nonNull.offset()); + + // If it is null, skip value in JSON. + ____.aload(OptimizedClassConstants.ReadLocals.JSON_READER) + .invokevirtual(GsonClassConstants.NAME_JSON_READER, + GsonClassConstants.METHOD_NAME_SKIP_VALUE, + GsonClassConstants.METHOD_TYPE_SKIP_VALUE); + // Return null as result. + ____.aconst_null() + .areturn(); + + // If the next value is not null, create an instance of the domain class. + ____.label(nonNull); + + if (instanceCreatorClasses.getClass(objectClassName) == null) + { + ____.new_(objectClassName) + .dup() + .invokespecial(objectClassName, + ClassConstants.METHOD_NAME_INIT, + ClassConstants.METHOD_TYPE_INIT) + .astore(OptimizedClassConstants.ReadLocals.VALUE); + } + else + { + // For classes for which an InstanceCreator is registered, we + // let the instance creator instantiate the class. + ____.aload(OptimizedClassConstants.ReadLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_GSON, + OptimizedClassConstants.FIELD_TYPE_GSON) + .getfield(GsonClassConstants.NAME_GSON, + GsonClassConstants.FIELD_NAME_INSTANCE_CREATORS, + GsonClassConstants.FIELD_TYPE_INSTANCE_CREATORS) + .ldc(instanceCreatorClasses.getClass(objectClassName)) + .invokevirtual(ClassConstants.NAME_JAVA_UTIL_MAP, + ClassConstants.METHOD_NAME_MAP_GET, + ClassConstants.METHOD_TYPE_MAP_GET) + .checkcast(GsonClassConstants.NAME_INSTANCE_CREATOR) + .ldc(instanceCreatorClasses.getClass(objectClassName)) + .invokevirtual(GsonClassConstants.NAME_INSTANCE_CREATOR, + GsonClassConstants.METHOD_NAME_CREATE_INSTANCE, + GsonClassConstants.METHOD_TYPE_CREATE_INSTANCE) + .checkcast(objectClassName) + .astore(OptimizedClassConstants.ReadLocals.VALUE); + } + + // Deserialize object by calling its fromJson$ method. + ____.aload(OptimizedClassConstants.ReadLocals.VALUE) + .aload(OptimizedClassConstants.ReadLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_GSON, + OptimizedClassConstants.FIELD_TYPE_GSON) + .aload(OptimizedClassConstants.ReadLocals.JSON_READER) + .aload(OptimizedClassConstants.ReadLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_OPTIMIZED_JSON_READER, + OptimizedClassConstants.FIELD_TYPE_OPTIMIZED_JSON_READER) + .invokevirtual(objectClassName, + methodNameFromJson, + OptimizedClassConstants.METHOD_TYPE_FROM_JSON); + + // Return deserialized object. + ____.aload(OptimizedClassConstants.ReadLocals.VALUE) + .areturn(); + + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + } + + + /** + * Visits the code attribute of the the write() method of the TypeAdapter and + * provides it with a proper implementation for enum types. + */ + private class EnumWriteImplementer + extends SimplifiedVisitor + implements AttributeVisitor + { + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + InstructionSequenceBuilder ____ = new InstructionSequenceBuilder((ProgramClass)clazz); + + Label nonNull = codeAttributeEditor.label(); + Label end = codeAttributeEditor.label(); + Label writeValue = codeAttributeEditor.label(); + + // Check if the passed value is null. + ____.aload(OptimizedClassConstants.WriteLocals.VALUE) + .ifnonnull(nonNull.offset()); + + // If it is null, write null value in JSON. + ____.aload(OptimizedClassConstants.WriteLocals.JSON_WRITER) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_NULL_VALUE, + GsonClassConstants.METHOD_TYPE_NULL_VALUE) + .pop() + .goto_(end.offset()); + + // If it is not null, serialize value. + Map javaToJsonValueNames = serializationIndexMap.classJsonInfos.get(objectClassName).javaToJsonFieldNames; + Map jsonFieldIndices = serializationIndexMap.jsonFieldIndices; + + ____.label(nonNull) + .aload(OptimizedClassConstants.WriteLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_OPTIMIZED_JSON_WRITER, + OptimizedClassConstants.FIELD_TYPE_OPTIMIZED_JSON_WRITER) + .aload(OptimizedClassConstants.WriteLocals.JSON_WRITER) + .aload(OptimizedClassConstants.WriteLocals.VALUE); + + for (String javaValueName: javaToJsonValueNames.keySet()) + { + Label label = codeAttributeEditor.label(); + String jsonValueName = javaToJsonValueNames.get(javaValueName)[0]; + + ____.dup() + .getstatic(objectClassName, + javaValueName, + ClassUtil.internalTypeFromClassName(objectClassName)) + .ifacmpne(label.offset()) + .pop() + .ldc(jsonFieldIndices.get(jsonValueName).intValue()) + .goto_(writeValue.offset()) + .label(label); + } + ____.pop() + .iconst_m1(); + + ____.label(writeValue) + .invokevirtual(OptimizedClassConstants.NAME_OPTIMIZED_JSON_WRITER, + OptimizedClassConstants.METHOD_NAME_VALUE, + OptimizedClassConstants.METHOD_TYPE_VALUE) + .label(end) + .return_(); + + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + } + + + /** + * Visits the code attribute of the the write() method of the TypeAdapter and + * provides it with a proper implementation for non-enum types. + */ + private class WriteImplementer + extends SimplifiedVisitor + implements AttributeVisitor + { + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) + { + codeAttributeEditor.reset(codeAttribute.u4codeLength); + InstructionSequenceBuilder ____ = + new InstructionSequenceBuilder((ProgramClass)clazz); + + Integer classIndex = serializationIndexMap.classIndices.get(objectClassName); + String methodNameToJson = OptimizedClassConstants.METHOD_NAME_TO_JSON + classIndex; + + CodeAttributeEditor.Label nonNull = codeAttributeEditor.label(); + CodeAttributeEditor.Label end = codeAttributeEditor.label(); + + // Check if the passed value is null. + ____.aload(OptimizedClassConstants.WriteLocals.VALUE) + .ifnonnull(nonNull.offset()); + + // If it is null, write null value in JSON. + ____.aload(OptimizedClassConstants.WriteLocals.JSON_WRITER) + .invokevirtual(GsonClassConstants.NAME_JSON_WRITER, + GsonClassConstants.METHOD_NAME_NULL_VALUE, + GsonClassConstants.METHOD_TYPE_NULL_VALUE) + .pop() + .goto_(end.offset()); + + // If the next value is not null, serialize object by calling its toJson$ method. + ____.label(nonNull) + .aload(OptimizedClassConstants.WriteLocals.VALUE) + .checkcast(objectClassName) + .aload(OptimizedClassConstants.WriteLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_GSON, + OptimizedClassConstants.FIELD_TYPE_GSON) + .aload(OptimizedClassConstants.WriteLocals.JSON_WRITER) + .aload(OptimizedClassConstants.WriteLocals.THIS) + .getfield(typeAdapterClassName, + OptimizedClassConstants.FIELD_NAME_OPTIMIZED_JSON_WRITER, + OptimizedClassConstants.FIELD_TYPE_OPTIMIZED_JSON_WRITER) + .invokevirtual(objectClassName, + methodNameToJson, + OptimizedClassConstants.METHOD_TYPE_TO_JSON) + .label(end) + .return_(); + + codeAttributeEditor.replaceInstruction(0, ____.instructions()); + codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedTypeAdapter.java proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedTypeAdapter.java --- proguard-6.0.3/core/src/proguard/optimize/gson/_OptimizedTypeAdapter.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/_OptimizedTypeAdapter.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +/** + * Marker interface for all injected optimized GSON type adapters. This allows + * recognizing these type adapters and giving them the right priority. + * + * @author Lars Vandenbergh + */ +public interface _OptimizedTypeAdapter +{ +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/package.html proguard-6.2.0/core/src/proguard/optimize/gson/package.html --- proguard-6.0.3/core/src/proguard/optimize/gson/package.html 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/package.html 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,3 @@ + +This package contains classes for optimizing usages of the Gson library for serializing and deserialing Json. + \ No newline at end of file diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/TypeArgumentFinder.java proguard-6.2.0/core/src/proguard/optimize/gson/TypeArgumentFinder.java --- proguard-6.0.3/core/src/proguard/optimize/gson/TypeArgumentFinder.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/TypeArgumentFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,252 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.evaluation.TracedStack; +import proguard.evaluation.value.InstructionOffsetValue; +import proguard.optimize.evaluation.PartialEvaluator; +import proguard.util.ArrayUtil; + +/** + * This instruction visitor searches for the types that are passed as arguments + * to a method. The visited instruction is assumed to be the producer that put + * the types on the stack. + * + * It can recognize Class objects and Type objects that were derived from + * TypeToken.getType(). + * + * @author Lars Vandenbergh + */ +class TypeArgumentFinder +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor +{ + private final ClassPool programClassPool; + private final PartialEvaluator partialEvaluator; + String[] typeArgumentClasses; + + + /** + * Creates a new TypeArgumentFinder. + * + * @param programClassPool the program class pool used for looking up + * class references. + * @param partialEvaluator the partial evaluator used to evaluate visited + * code attributes. + */ + TypeArgumentFinder(ClassPool programClassPool, + PartialEvaluator partialEvaluator) + { + this.programClassPool = programClassPool; + this.partialEvaluator = partialEvaluator; + } + + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) {} + + @Override + public void visitVariableInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + VariableInstruction variableInstruction) + { + if (variableInstruction.canonicalOpcode() == InstructionConstants.OP_ALOAD) + { + // Find the operation that stored the loaded Type. + LastStoreFinder lastStoreFinder = new LastStoreFinder(variableInstruction.variableIndex); + codeAttribute.instructionsAccept(clazz, method, 0, offset, lastStoreFinder); + + if (lastStoreFinder.lastStore != null) + { + // Find out which instruction produced the stored Type. + TracedStack stackBeforeStore = partialEvaluator.getStackBefore(lastStoreFinder.lastStoreOffset); + InstructionOffsetValue instructionOffsetValue = stackBeforeStore.getTopProducerValue(0).instructionOffsetValue(); + + // Derive the signature of the subclass of TypeToken from which the Type is retrieved. + TypeTokenSignatureFinder typeTokenFinder = new TypeTokenSignatureFinder(); + for (int offsetIndex = 0; offsetIndex < instructionOffsetValue.instructionOffsetCount(); offsetIndex++) + { + int instructionOffset = instructionOffsetValue.instructionOffset(offsetIndex); + codeAttribute.instructionAccept(clazz, method, instructionOffset, typeTokenFinder); + } + + // Derive the classes from the signature of the TypeToken subclass. + if (typeTokenFinder.typeTokenSignature != null) + { + typeArgumentClasses = new String[0]; + Clazz[] referencedClasses = typeTokenFinder.typeTokenSignature.referencedClasses; + for (Clazz referencedClass : referencedClasses) + { + if (referencedClass!= null && + !referencedClass.getName().equals(GsonClassConstants.NAME_TYPE_TOKEN)) + { + typeArgumentClasses = ArrayUtil.add(typeArgumentClasses, + typeArgumentClasses.length, + referencedClass.getName()); + } + } + } + } + } + } + + + public void visitConstantInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + ConstantInstruction constantInstruction) + { + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + + // Implementations for ConstantVisitor. + + + @Override + public void visitAnyConstant(Clazz clazz, Constant constant) + { + } + + @Override + public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) + { + typeArgumentClasses = new String[] { refConstant.getClassName(clazz) }; + } + + @Override + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + typeArgumentClasses = new String[] { classConstant.getName(clazz) }; + } + + private static class LastStoreFinder + extends SimplifiedVisitor + implements InstructionVisitor + { + private final int variableIndex; + private int lastStoreOffset; + private VariableInstruction lastStore; + + public LastStoreFinder(int variableIndex) + { + this.variableIndex = variableIndex; + } + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) + { + } + + @Override + public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) + { + if(variableInstruction.variableIndex == variableIndex && + variableInstruction.canonicalOpcode() == InstructionConstants.OP_ASTORE){ + lastStoreOffset = offset; + lastStore = variableInstruction; + } + } + } + + private class TypeTokenSignatureFinder + extends SimplifiedVisitor + implements InstructionVisitor, + ConstantVisitor, + AttributeVisitor + { + + private SignatureAttribute typeTokenSignature; + + // Implementations for InstructionVisitor. + + @Override + public void visitAnyInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + Instruction instruction) + { + } + + @Override + public void visitConstantInstruction(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + int offset, + ConstantInstruction constantInstruction) + { + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + + // Implementations for ConstantVisitor. + + @Override + public void visitAnyConstant(Clazz clazz, Constant constant) + { + } + + @Override + public void visitMethodrefConstant(Clazz clazz, + MethodrefConstant methodrefConstant) + { + if (methodrefConstant.referencedClass.getName().equals(GsonClassConstants.NAME_TYPE_TOKEN) && + methodrefConstant.getName(clazz).equals(GsonClassConstants.METHOD_NAME_GET_TYPE)) + { + programClassPool.classAccept(methodrefConstant.getClassName(clazz), + new AllAttributeVisitor(this)); + } + } + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) + { + } + + @Override + public void visitSignatureAttribute(Clazz clazz, + SignatureAttribute signatureAttribute) + { + typeTokenSignature = signatureAttribute; + } + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/gson/TypeParameterClassChecker.java proguard-6.2.0/core/src/proguard/optimize/gson/TypeParameterClassChecker.java --- proguard-6.0.3/core/src/proguard/optimize/gson/TypeParameterClassChecker.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/gson/TypeParameterClassChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,83 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.optimize.gson; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.*; + +/** + * Checks whether a visited class contains fields that have generic type + * parameters. + * + * For example: + * + *

+ * public class Foo
+ * {
+ *     private T field;
+ * }
+ * 
+ * + * @author Lars Vandenbergh + */ +class TypeParameterClassChecker +extends SimplifiedVisitor +implements ClassVisitor, + AttributeVisitor +{ + public boolean hasFieldWithTypeParameter; + + + // Implementations for ClassVisitor. + + @Override + public void visitAnyClass(Clazz clazz) {} + + + @Override + public void visitProgramClass(ProgramClass programClass) + { + programClass.fieldsAccept(new AllAttributeVisitor(this)); + } + + + // Implementations for AttributeVisitor. + + @Override + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + @Override + public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute) + { + String fieldSignature = signatureAttribute.getSignature(clazz); + hasFieldWithTypeParameter = hasFieldWithTypeParameter || + fieldSignature.startsWith("T") || + fieldSignature.contains(";"; + int signatureIndex = constantPoolEditor.addUtf8Constant(classSignature); + AttributesEditor attributesEditor = new AttributesEditor(subClass, false); + attributesEditor.addAttribute(new SignatureAttribute(attributeNameIndex, signatureIndex)); + + return subClass; + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/AccessMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/AccessMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/AccessMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/AccessMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -71,6 +71,13 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + // Check the bootstrap method. + dynamicConstant.bootstrapMethodHandleAccept(clazz, this); + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { // Check the bootstrap method. diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/BackwardBranchMarker.java proguard-6.2.0/core/src/proguard/optimize/info/BackwardBranchMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/BackwardBranchMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/BackwardBranchMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/CatchExceptionMarker.java proguard-6.2.0/core/src/proguard/optimize/info/CatchExceptionMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/CatchExceptionMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/CatchExceptionMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/CaughtClassFilter.java proguard-6.2.0/core/src/proguard/optimize/info/CaughtClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/CaughtClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/CaughtClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/CaughtClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/CaughtClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/CaughtClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/CaughtClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ClassOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/ClassOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/ClassOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ClassOptimizationInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/CodeAttributeOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/CodeAttributeOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/CodeAttributeOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/CodeAttributeOptimizationInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/DotClassFilter.java proguard-6.2.0/core/src/proguard/optimize/info/DotClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/DotClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/DotClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/DotClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/DotClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/DotClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/DotClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/DynamicInvocationMarker.java proguard-6.2.0/core/src/proguard/optimize/info/DynamicInvocationMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/DynamicInvocationMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/DynamicInvocationMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/EscapingClassFilter.java proguard-6.2.0/core/src/proguard/optimize/info/EscapingClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/EscapingClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/EscapingClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/EscapingClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/EscapingClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/EscapingClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/EscapingClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ExceptionInstructionChecker.java proguard-6.2.0/core/src/proguard/optimize/info/ExceptionInstructionChecker.java --- proguard-6.0.3/core/src/proguard/optimize/info/ExceptionInstructionChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ExceptionInstructionChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/FieldOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/FieldOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/FieldOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/FieldOptimizationInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -33,6 +33,9 @@ public class FieldOptimizationInfo extends SimplifiedVisitor { + protected Value value; + + public boolean isKept() { return true; @@ -63,9 +66,15 @@ } + public void setValue(Value value) + { + this.value = value; + } + + public Value getValue() { - return null; + return value; } diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/FinalFieldAssignmentMarker.java proguard-6.2.0/core/src/proguard/optimize/info/FinalFieldAssignmentMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/FinalFieldAssignmentMarker.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/FinalFieldAssignmentMarker.java 2019-10-04 12:07:45.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2018 GuardSquare NV + */ +package proguard.optimize.info; + +import proguard.classfile.*; +import proguard.classfile.attribute.CodeAttribute; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.instruction.*; +import proguard.classfile.instruction.visitor.InstructionVisitor; +import proguard.classfile.util.SimplifiedVisitor; + +/** + * This InstructionVisitor marks whether a final field is assigned + * in the methods whose instructions it visits. + * + * @author Thomas Neidhart + */ +public class FinalFieldAssignmentMarker +extends SimplifiedVisitor +implements InstructionVisitor, + ConstantVisitor +{ + private Method referencedMethod; + + + // Implementations for InstructionVisitor. + + public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} + + + @Override + public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) + { + if (constantInstruction.opcode == InstructionConstants.OP_PUTSTATIC || + constantInstruction.opcode == InstructionConstants.OP_PUTFIELD) + { + referencedMethod = method; + clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this); + } + } + + + // Implementations for ConstantVisitor. + + @Override + public void visitAnyConstant(Clazz clazz, Constant constant) {} + + + @Override + public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) + { + if (fieldrefConstant.referencedMember != null && + (fieldrefConstant.referencedMember.getAccessFlags() & ClassConstants.ACC_FINAL) != 0) + { + setAssignsFinalField(referencedMethod); + } + } + + + // Small utility methods. + + private static void setAssignsFinalField(Method method) + { + ProgramMethodOptimizationInfo.getProgramMethodOptimizationInfo(method).setAssignsFinalField(); + } + + + /** + * Returns whether the given method assigns a final field. + */ + public static boolean assignsFinalField(Method method) + { + return MethodOptimizationInfo.getMethodOptimizationInfo(method).assignsFinalField(); + } +} diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/InstanceofClassFilter.java proguard-6.2.0/core/src/proguard/optimize/info/InstanceofClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/InstanceofClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/InstanceofClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/InstanceofClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/InstanceofClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/InstanceofClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/InstanceofClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/InstantiationClassFilter.java proguard-6.2.0/core/src/proguard/optimize/info/InstantiationClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/InstantiationClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/InstantiationClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/InstantiationClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/InstantiationClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/InstantiationClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/InstantiationClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/MethodInvocationMarker.java proguard-6.2.0/core/src/proguard/optimize/info/MethodInvocationMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/MethodInvocationMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/MethodInvocationMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/MethodOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/MethodOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/MethodOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/MethodOptimizationInfo.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -36,6 +36,7 @@ protected boolean hasNoExternalSideEffects = false; protected boolean hasNoEscapingParameters = false; protected boolean hasNoExternalReturnValues = false; + protected Value returnValue = null; public boolean isKept() @@ -95,6 +96,18 @@ } + public void setReturnValue(Value returnValue) + { + this.returnValue = returnValue; + } + + + public Value getReturnValue() + { + return returnValue; + } + + // Methods that may be specialized. public boolean hasSideEffects() @@ -157,6 +170,12 @@ } + public boolean assignsFinalField() + { + return true; + } + + public boolean returnsWithNonEmptyStack() { return false; @@ -272,12 +291,6 @@ } - public Value getReturnValue() - { - return null; - } - - public static void setMethodOptimizationInfo(Clazz clazz, Method method) { MethodLinker.lastMember(method).setVisitorInfo(new MethodOptimizationInfo()); diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/MutableBoolean.java proguard-6.2.0/core/src/proguard/optimize/info/MutableBoolean.java --- proguard-6.0.3/core/src/proguard/optimize/info/MutableBoolean.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/MutableBoolean.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NoEscapingParametersMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NoEscapingParametersMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NoEscapingParametersMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NoEscapingParametersMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NoExternalReturnValuesMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NoExternalReturnValuesMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NoExternalReturnValuesMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NoExternalReturnValuesMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NoExternalSideEffectMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NoExternalSideEffectMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NoExternalSideEffectMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NoExternalSideEffectMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NonEmptyStackReturnMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NonEmptyStackReturnMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NonEmptyStackReturnMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NonEmptyStackReturnMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NonPrivateMemberMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NonPrivateMemberMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NonPrivateMemberMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NonPrivateMemberMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NoSideEffectClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NoSideEffectClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NoSideEffectClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NoSideEffectClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/NoSideEffectMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/NoSideEffectMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/NoSideEffectMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/NoSideEffectMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/OptimizationCodeAttributeFilter.java proguard-6.2.0/core/src/proguard/optimize/info/OptimizationCodeAttributeFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/OptimizationCodeAttributeFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/OptimizationCodeAttributeFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ParameterEscapedMarker.java proguard-6.2.0/core/src/proguard/optimize/info/ParameterEscapedMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/ParameterEscapedMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ParameterEscapedMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ParameterEscapeMarker.java proguard-6.2.0/core/src/proguard/optimize/info/ParameterEscapeMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/ParameterEscapeMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ParameterEscapeMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -283,6 +283,12 @@ markEscapingParameters(method, offset, 0); break; + case InstructionConstants.OP_GETFIELD: + // Mark the owner of the field. The owner sort of escapes when + // the field is retrieved. [DGD-1279] (test2181) + markEscapingParameters(method, offset, 0); + break; + case InstructionConstants.OP_PUTFIELD: // Mark reference parameters whose field is modified. markModifiedParameters(method, diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ParameterUsageMarker.java proguard-6.2.0/core/src/proguard/optimize/info/ParameterUsageMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/ParameterUsageMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ParameterUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ProgramClassOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/ProgramClassOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/ProgramClassOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ProgramClassOptimizationInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ProgramClassOptimizationInfoSetter.java proguard-6.2.0/core/src/proguard/optimize/info/ProgramClassOptimizationInfoSetter.java --- proguard-6.0.3/core/src/proguard/optimize/info/ProgramClassOptimizationInfoSetter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ProgramClassOptimizationInfoSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ProgramFieldOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/ProgramFieldOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/ProgramFieldOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ProgramFieldOptimizationInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -45,7 +45,6 @@ private volatile boolean isRead; private volatile boolean canBeMadePrivate = true; private volatile ReferenceValue referencedClass; - private volatile Value value; public ProgramFieldOptimizationInfo(Clazz clazz, Field field) @@ -61,11 +60,11 @@ public ProgramFieldOptimizationInfo(ProgramFieldOptimizationInfo programFieldOptimizationInfo) { + this.value = programFieldOptimizationInfo.value; this.isWritten = programFieldOptimizationInfo.isWritten; this.isRead = programFieldOptimizationInfo.isRead; this.canBeMadePrivate = programFieldOptimizationInfo.canBeMadePrivate; this.referencedClass = programFieldOptimizationInfo.referencedClass; - this.value = programFieldOptimizationInfo.value; } @@ -158,12 +157,6 @@ } - public Value getValue() - { - return value; - } - - // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ProgramMemberOptimizationInfoSetter.java proguard-6.2.0/core/src/proguard/optimize/info/ProgramMemberOptimizationInfoSetter.java --- proguard-6.0.3/core/src/proguard/optimize/info/ProgramMemberOptimizationInfoSetter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ProgramMemberOptimizationInfoSetter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ProgramMethodOptimizationInfo.java proguard-6.2.0/core/src/proguard/optimize/info/ProgramMethodOptimizationInfo.java --- proguard-6.0.3/core/src/proguard/optimize/info/ProgramMethodOptimizationInfo.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ProgramMethodOptimizationInfo.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -47,6 +47,7 @@ private volatile boolean accessesPackageCode = false; private volatile boolean accessesProtectedCode = false; private volatile boolean hasSynchronizedBlock = false; + private volatile boolean assignsFinalField = false; private volatile boolean returnsWithNonEmptyStack = false; private volatile int invocationCount = 0; private volatile int parameterSize = 0; @@ -59,7 +60,6 @@ private volatile long returnedParameters = 0L; private volatile boolean returnsNewInstances = false; private volatile boolean returnsExternalValues = false; - private volatile Value returnValue; /** @@ -68,14 +68,10 @@ public ProgramMethodOptimizationInfo(Clazz clazz, Method method) { // Set up an array of the right size for storing information about the - // passed parameters. + // passed parameters (including 'this', for non-static methods). int parameterCount = - ClassUtil.internalMethodParameterCount(method.getDescriptor(clazz)); - - if ((method.getAccessFlags() & ClassConstants.ACC_STATIC) == 0) - { - parameterCount++; - } + ClassUtil.internalMethodParameterCount(method.getDescriptor(clazz), + method.getAccessFlags()); parameters = parameterCount == 0 ? EMPTY_PARAMETERS : @@ -209,6 +205,18 @@ } + public void setAssignsFinalField() + { + assignsFinalField = true; + } + + + public boolean assignsFinalField() + { + return assignsFinalField; + } + + public void setReturnsWithNonEmptyStack() { returnsWithNonEmptyStack = true; @@ -259,7 +267,9 @@ public boolean hasUnusedParameters() { - return (usedParameters | -1L << parameterSize) != -1L; + return parameterSize < 64 ? + (usedParameters | -1L << parameterSize) != -1L : + usedParameters != -1L ; } @@ -490,19 +500,6 @@ } - public Value getReturnValue() - { - return returnValue; - } - - - // For setting enum return values. - public synchronized void setReturnValue(Value returnValue) - { - this.returnValue = returnValue; - } - - public synchronized void merge(MethodOptimizationInfo other) { this.catchesExceptions |= other.catchesExceptions(); @@ -513,6 +510,7 @@ this.accessesPackageCode |= other.accessesPackageCode(); this.accessesProtectedCode |= other.accessesProtectedCode(); this.hasSynchronizedBlock |= other.hasSynchronizedBlock(); + this.assignsFinalField |= other.assignsFinalField(); // Some of these should actually be recomputed, since these are // relative to the method: diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ReadWriteFieldMarker.java proguard-6.2.0/core/src/proguard/optimize/info/ReadWriteFieldMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/ReadWriteFieldMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ReadWriteFieldMarker.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -48,6 +48,8 @@ private final MutableBoolean repeatTrigger; + private final boolean markReading; + private final boolean markWriting; // Parameters for the visitor methods. @@ -58,11 +60,32 @@ /** - * Creates a new ReadWriteFieldMarker. + * Creates a new ReadWriteFieldMarker that marks fields that are read and + * fields that are written. + * @param repeatTrigger a mutable boolean flag that is set whenever a field + * gets a mark that it didn't have before. */ public ReadWriteFieldMarker(MutableBoolean repeatTrigger) { + this(repeatTrigger, true, true); + } + + + /** + * Creates a new ReadWriteFieldMarker that marks fields that are read and + * fields that are written, as specified. + * @param repeatTrigger a mutable boolean flag that is set whenever a field + * gets a mark that it didn't have before. + * @param markReading specifies whether fields may be marked as read. + * @param markWriting specifies whether fields may be marked as written. + */ + public ReadWriteFieldMarker(MutableBoolean repeatTrigger, + boolean markReading, + boolean markWriting) + { this.repeatTrigger = repeatTrigger; + this.markReading = markReading; + this.markWriting = markWriting; } @@ -132,22 +155,22 @@ public void visitProgramField(ProgramClass programClass, ProgramField programField) { // Mark the field if it is being read from. - if (reading) + if (markReading && reading) { - markAsRead(programField); + markAsRead(programClass, programField); } // Mark the field if it is being written to. - if (writing) + if (markWriting && writing) { - markAsWritten(programField); + markAsWritten(programClass, programField); } } // Small utility methods. - private void markAsRead(Field field) + private void markAsRead(Clazz clazz, Field field) { FieldOptimizationInfo fieldOptimizationInfo = FieldOptimizationInfo.getFieldOptimizationInfo(field); @@ -155,6 +178,11 @@ if (!fieldOptimizationInfo.isRead() && fieldOptimizationInfo instanceof ProgramFieldOptimizationInfo) { + if (DEBUG) + { + System.out.println("ReadWriteFieldMarker: marking as read: "+clazz.getName()+"."+field.getName(clazz)); + } + ((ProgramFieldOptimizationInfo)fieldOptimizationInfo).setRead(); repeatTrigger.set(); @@ -168,7 +196,7 @@ } - private void markAsWritten(Field field) + private void markAsWritten(Clazz clazz, Field field) { FieldOptimizationInfo fieldOptimizationInfo = FieldOptimizationInfo.getFieldOptimizationInfo(field); @@ -176,6 +204,11 @@ if (!fieldOptimizationInfo.isWritten() && fieldOptimizationInfo instanceof ProgramFieldOptimizationInfo) { + if (DEBUG) + { + System.out.println("ReadWriteFieldMarker: marking as written: "+clazz.getName()+"."+field.getName(clazz)); + } + ((ProgramFieldOptimizationInfo)fieldOptimizationInfo).setWritten(); repeatTrigger.set(); diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/ReferenceEscapeChecker.java proguard-6.2.0/core/src/proguard/optimize/info/ReferenceEscapeChecker.java --- proguard-6.0.3/core/src/proguard/optimize/info/ReferenceEscapeChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/ReferenceEscapeChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/RepeatedClassPoolVisitor.java proguard-6.2.0/core/src/proguard/optimize/info/RepeatedClassPoolVisitor.java --- proguard-6.0.3/core/src/proguard/optimize/info/RepeatedClassPoolVisitor.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/RepeatedClassPoolVisitor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SideEffectClassChecker.java proguard-6.2.0/core/src/proguard/optimize/info/SideEffectClassChecker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SideEffectClassChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SideEffectClassChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SideEffectClassFilter.java proguard-6.2.0/core/src/proguard/optimize/info/SideEffectClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/SideEffectClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SideEffectClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SideEffectClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/SideEffectClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SideEffectClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SideEffectClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SideEffectInstructionChecker.java proguard-6.2.0/core/src/proguard/optimize/info/SideEffectInstructionChecker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SideEffectInstructionChecker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SideEffectInstructionChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SideEffectMethodFilter.java proguard-6.2.0/core/src/proguard/optimize/info/SideEffectMethodFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/SideEffectMethodFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SideEffectMethodFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SideEffectMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/SideEffectMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SideEffectMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SideEffectMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SimpleEnumFilter.java proguard-6.2.0/core/src/proguard/optimize/info/SimpleEnumFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/SimpleEnumFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SimpleEnumFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SimpleEnumMarker.java proguard-6.2.0/core/src/proguard/optimize/info/SimpleEnumMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SimpleEnumMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SimpleEnumMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SuperInvocationMarker.java proguard-6.2.0/core/src/proguard/optimize/info/SuperInvocationMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SuperInvocationMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SuperInvocationMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/SynchronizedBlockMethodMarker.java proguard-6.2.0/core/src/proguard/optimize/info/SynchronizedBlockMethodMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/SynchronizedBlockMethodMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/SynchronizedBlockMethodMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/UnusedParameterMethodFilter.java proguard-6.2.0/core/src/proguard/optimize/info/UnusedParameterMethodFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/UnusedParameterMethodFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/UnusedParameterMethodFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/UnusedParameterOptimizationInfoUpdater.java proguard-6.2.0/core/src/proguard/optimize/info/UnusedParameterOptimizationInfoUpdater.java --- proguard-6.0.3/core/src/proguard/optimize/info/UnusedParameterOptimizationInfoUpdater.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/UnusedParameterOptimizationInfoUpdater.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/UsedParameterFilter.java proguard-6.2.0/core/src/proguard/optimize/info/UsedParameterFilter.java --- proguard-6.0.3/core/src/proguard/optimize/info/UsedParameterFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/UsedParameterFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/VariableUsageMarker.java proguard-6.2.0/core/src/proguard/optimize/info/VariableUsageMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/VariableUsageMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/VariableUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/info/WrapperClassMarker.java proguard-6.2.0/core/src/proguard/optimize/info/WrapperClassMarker.java --- proguard-6.0.3/core/src/proguard/optimize/info/WrapperClassMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/info/WrapperClassMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/KeepMarker.java proguard-6.2.0/core/src/proguard/optimize/KeepMarker.java --- proguard-6.0.3/core/src/proguard/optimize/KeepMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/KeepMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/KeptClassFilter.java proguard-6.2.0/core/src/proguard/optimize/KeptClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/KeptClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/KeptClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/KeptMemberFilter.java proguard-6.2.0/core/src/proguard/optimize/KeptMemberFilter.java --- proguard-6.0.3/core/src/proguard/optimize/KeptMemberFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/KeptMemberFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/MemberDescriptorSpecializer.java proguard-6.2.0/core/src/proguard/optimize/MemberDescriptorSpecializer.java --- proguard-6.0.3/core/src/proguard/optimize/MemberDescriptorSpecializer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/MemberDescriptorSpecializer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -98,17 +98,18 @@ { // All parameters of non-static methods are shifted by one in the local // variable frame. - int firstParameterIndex = - (programMethod.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; + boolean isStatic = + (programMethod.getAccessFlags() & ClassConstants.ACC_STATIC) != 0; + int parameterStart = isStatic ? 0 : 1; int parameterCount = - ClassUtil.internalMethodParameterCount(programMethod.getDescriptor(programClass)); + ClassUtil.internalMethodParameterCount(programMethod.getDescriptor(programClass), + isStatic); int classIndex = 0; // Go over the parameters. - for (int parameterIndex = firstParameterIndex; parameterIndex < parameterCount; parameterIndex++) + for (int parameterIndex = parameterStart; parameterIndex < parameterCount; parameterIndex++) { Value parameterValue = StoringInvocationUnit.getMethodParameterValue(programMethod, parameterIndex); if (parameterValue.computationalType() == Value.TYPE_REFERENCE) diff -Nru proguard-6.0.3/core/src/proguard/optimize/MethodDescriptorShrinker.java proguard-6.2.0/core/src/proguard/optimize/MethodDescriptorShrinker.java --- proguard-6.0.3/core/src/proguard/optimize/MethodDescriptorShrinker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/MethodDescriptorShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -85,7 +85,7 @@ // Update the descriptor if it has any unused parameters. String descriptor = programMethod.getDescriptor(programClass); - String newDescriptor = shrinkDescriptor(programMethod, descriptor); + String newDescriptor = shrinkDescriptor(programMethod, descriptor, 0); if (!newDescriptor.equals(descriptor)) { @@ -116,6 +116,7 @@ programMethod.referencedClasses = shrinkReferencedClasses(programMethod, descriptor, + 0, programMethod.referencedClasses); // Finally, update the descriptor itself. @@ -149,8 +150,18 @@ } // Compute the new signature. - String signature = signatureAttribute.getSignature(clazz); - String newSignature = shrinkDescriptor(method, signature); + String signature = signatureAttribute.getSignature(clazz); + + // Constructors of enum classes and of non-static inner classes may + // start with one or two synthetic parameters, which are not part + // of the signature. + int syntheticParametersSize = + new InternalTypeEnumeration(method.getDescriptor(clazz)).typesSize() - + new InternalTypeEnumeration(signature).typesSize(); + + String newSignature = shrinkDescriptor(method, + signature, + syntheticParametersSize); if (!newSignature.equals(signature)) { @@ -162,6 +173,7 @@ signatureAttribute.referencedClasses = shrinkReferencedClasses(method, signature, + syntheticParametersSize, signatureAttribute.referencedClasses); if (DEBUG) @@ -177,20 +189,41 @@ int[] annotationsCounts = parameterAnnotationsAttribute.u2parameterAnnotationsCount; Annotation[][] annotations = parameterAnnotationsAttribute.parameterAnnotations; + String descriptor = method.getDescriptor(clazz); + + // Constructors of enum classes and of non-static inner classes may + // start with one or two synthetic parameters, which are not part + // of the signature and not counted for parameter annotations. + int syntheticParameterCount = + new InternalTypeEnumeration(descriptor).typeCount() - + parameterAnnotationsAttribute.u1parametersCount; + + int syntheticParametersSize = + ClassUtil.internalMethodVariableIndex(descriptor, + true, + syntheticParameterCount); + // All parameters of non-static methods are shifted by one in the local // variable frame. int parameterIndex = - (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; + syntheticParametersSize + + ((method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? + 0 : 1); int annotationIndex = 0; int newAnnotationIndex = 0; // Go over the parameters. - String descriptor = method.getDescriptor(clazz); InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(descriptor); + // Skip synthetic parameters that don't have annotations. + for (int counter = 0; counter < syntheticParameterCount; counter++) + { + internalTypeEnumeration.nextType(); + } + + // Shrink the annotations of the actual parameters. while (internalTypeEnumeration.hasMoreTypes()) { String type = internalTypeEnumeration.nextType(); @@ -222,13 +255,17 @@ /** * Returns a shrunk descriptor or signature of the given method. */ - private String shrinkDescriptor(Method method, String descriptor) + private String shrinkDescriptor(Method method, + String descriptor, + int syntheticParametersSize) { + // Signatures only start after any synthetic parameters. // All parameters of non-static methods are shifted by one in the local // variable frame. int parameterIndex = - (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; + syntheticParametersSize + + ((method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? + 0 : 1); InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(descriptor); @@ -269,15 +306,18 @@ */ private Clazz[] shrinkReferencedClasses(Method method, String descriptor, + int syntheticParametersSize, Clazz[] referencedClasses) { if (referencedClasses != null) { + // Signatures only start after any synthetic parameters. // All parameters of non-static methods are shifted by one in the local // variable frame. int parameterIndex = - (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? - 0 : 1; + syntheticParametersSize + + ((method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0 ? + 0 : 1); InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(descriptor); diff -Nru proguard-6.0.3/core/src/proguard/optimize/MethodStaticizer.java proguard-6.2.0/core/src/proguard/optimize/MethodStaticizer.java --- proguard-6.0.3/core/src/proguard/optimize/MethodStaticizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/MethodStaticizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/OptimizationInfoClassFilter.java proguard-6.2.0/core/src/proguard/optimize/OptimizationInfoClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/OptimizationInfoClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/OptimizationInfoClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/OptimizationInfoMemberFilter.java proguard-6.2.0/core/src/proguard/optimize/OptimizationInfoMemberFilter.java --- proguard-6.0.3/core/src/proguard/optimize/OptimizationInfoMemberFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/OptimizationInfoMemberFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/Optimizer.java proguard-6.2.0/core/src/proguard/optimize/Optimizer.java --- proguard-6.0.3/core/src/proguard/optimize/Optimizer.java 2018-04-12 10:46:17.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/Optimizer.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -47,6 +47,7 @@ { public static final boolean DETAILS = System.getProperty("optd") != null; + public static final String LIBRARY_GSON = "library/gson"; private static final String CLASS_MARKING_FINAL = "class/marking/final"; private static final String CLASS_UNBOXING_ENUM = "class/unboxing/enum"; private static final String CLASS_MERGING_VERTICAL = "class/merging/vertical"; @@ -84,6 +85,7 @@ public static final String[] OPTIMIZATION_NAMES = new String[] { + LIBRARY_GSON, CLASS_MARKING_FINAL, CLASS_MERGING_VERTICAL, CLASS_MERGING_HORIZONTAL, @@ -119,6 +121,7 @@ private final Configuration configuration; + private final boolean libraryGson; private final boolean classMarkingFinal; private final boolean classUnboxingEnum; private final boolean classMergingVertical; @@ -167,6 +170,7 @@ new ListParser(new NameParser()).parse(configuration.optimizations) : new ConstantMatcher(true); + libraryGson = filter.matches(LIBRARY_GSON); classMarkingFinal = filter.matches(CLASS_MARKING_FINAL); classUnboxingEnum = filter.matches(CLASS_UNBOXING_ENUM); classMergingVertical = filter.matches(CLASS_MERGING_VERTICAL); @@ -481,81 +485,83 @@ new MethodFinalizer(methodMarkingFinalCounter)))); } - // We'll repeatedly loop over all classes to mark read/write fields. - // side-effect methods, and escaping parameters. - final MutableBoolean repeatTrigger = new MutableBoolean(); - - // Create the various markers. - ReadWriteFieldMarker readWriteFieldMarker = - new ReadWriteFieldMarker(repeatTrigger); + // Give initial marks to read/written fields. side-effect methods, and + // escaping parameters. + final MutableBoolean mutableBoolean = new MutableBoolean(); - if (!fieldRemovalWriteonly) + if (fieldRemovalWriteonly) { - // Mark all fields as read/write. + // Mark fields that are read or written. The written flag is + // currently only needed for the write-only counter later on. + programClassPool.classesAccept( + new AllMethodVisitor( + new AllAttributeVisitor( + new AllInstructionVisitor( + new ReadWriteFieldMarker(mutableBoolean))))); + } + else + { + // Mark all fields as read and written. programClassPool.classesAccept( new AllFieldVisitor( - readWriteFieldMarker)); + new ReadWriteFieldMarker(mutableBoolean))); } - SideEffectMethodMarker sideEffectMethodMarker = - new SideEffectMethodMarker(repeatTrigger); - - ParameterEscapeMarker parameterEscapeMarker = - new ParameterEscapeMarker(repeatTrigger); - // Mark methods based on their headers. programClassPool.classesAccept( new AllMethodVisitor( new OptimizationInfoMemberFilter( new MultiMemberVisitor( - sideEffectMethodMarker, - parameterEscapeMarker + new SideEffectMethodMarker(mutableBoolean), + new ParameterEscapeMarker(mutableBoolean) )))); - { - // Mark fields based on the method instructions in methods - // without editable optimization info. - programClassPool.accept( - new TimedClassPoolVisitor("Marking field usage in kept methods", - new AllMethodVisitor( - new OptimizationInfoMemberFilter( - null, - - // member has no editable optimization info - new AllAttributeVisitor( - new AllInstructionVisitor( - readWriteFieldMarker)))))); + // Now repeatedly loop over all classes to mark read/written fields. + // side-effect methods, and escaping parameters. Marked elements like + // write-only fields or side-effect methods can each time affect the + // subsequent analysis, such as instructions that are used. We'll loop + // until the markers no longer trigger the repeat flag, meaning that + // all marks have converged. + // + // We'll mark classes in parallel threads, but with a shared repeat + // trigger. + final MutableBoolean repeatTrigger = new MutableBoolean(); - ParallelAllClassVisitor.ClassVisitorFactory markingClassVisitor = - new ParallelAllClassVisitor.ClassVisitorFactory() + programClassPool.accept( + new RepeatedClassPoolVisitor(repeatTrigger, + new TimedClassPoolVisitor("Marking fields, methods, and parameters", + new ParallelAllClassVisitor( + new ParallelAllClassVisitor.ClassVisitorFactory() + { + public ClassVisitor createClassVisitor() { - public ClassVisitor createClassVisitor() - { - ReferenceTracingValueFactory referenceTracingValueFactory1 = - new ReferenceTracingValueFactory(new TypedReferenceValueFactory()); - - PartialEvaluator partialEvaluator = - new PartialEvaluator(referenceTracingValueFactory1, - new ParameterTracingInvocationUnit(new BasicInvocationUnit(referenceTracingValueFactory1)), - false, - referenceTracingValueFactory1); - - InstructionUsageMarker instructionUsageMarker = - new InstructionUsageMarker(partialEvaluator, false); - - // Create the various markers. - ReadWriteFieldMarker readWriteFieldMarker = - new ReadWriteFieldMarker(repeatTrigger); + ReferenceTracingValueFactory referenceTracingValueFactory1 = + new ReferenceTracingValueFactory(new TypedReferenceValueFactory()); + PartialEvaluator partialEvaluator = + new PartialEvaluator(referenceTracingValueFactory1, + new ParameterTracingInvocationUnit(new BasicInvocationUnit(referenceTracingValueFactory1)), + false, + referenceTracingValueFactory1); + InstructionUsageMarker instructionUsageMarker = + new InstructionUsageMarker(partialEvaluator, false); + + // Create the various markers. + // They will be used as code attribute visitors and + // instruction visitors this time. + // We're currently marking read and written fields once, + // outside of these iterations, for better performance, + // at the cost of some effectiveness (test2209). + //ReadWriteFieldMarker readWriteFieldMarker = + // new ReadWriteFieldMarker(repeatTrigger); + SideEffectMethodMarker sideEffectMethodMarker = + new SideEffectMethodMarker(repeatTrigger); + ParameterEscapeMarker parameterEscapeMarker = + new ParameterEscapeMarker(repeatTrigger, partialEvaluator, false); - SideEffectMethodMarker sideEffectMethodMarker = - new SideEffectMethodMarker(repeatTrigger); - - ParameterEscapeMarker parameterEscapeMarker = - new ParameterEscapeMarker(repeatTrigger, partialEvaluator, false); - - return - new AllMethodVisitor( - new OptimizationInfoMemberFilter( + return + new AllMethodVisitor( + new OptimizationInfoMemberFilter( + // Methods with editable optimization info. new AllAttributeVisitor( new DebugAttributeVisitor("Marking fields, methods, and parameters", new MultiAttributeVisitor( @@ -565,22 +571,33 @@ new AllInstructionVisitor( instructionUsageMarker.necessaryInstructionFilter( new MultiInstructionVisitor( - readWriteFieldMarker, + // All read / write field instruction are already marked + // for all code (see above), there is no need to mark them again. + // If unused code is removed that accesses fields, the + // respective field will be removed in the next iteration. + // This is a trade-off between performance and correctness. + // TODO: improve the marking for read / write fields after + // performance improvements have been implemented. + //readWriteFieldMarker, sideEffectMethodMarker, parameterEscapeMarker - ))) - ))))); - } - }; + )))))) - // Mark fields, methods and parameters based on the method instructions - // for methods that have editable optimization info. - programClassPool.accept( - new RepeatedClassPoolVisitor(repeatTrigger, - new TimedClassPoolVisitor("Marking fields, methods and parameters", - new ParallelAllClassVisitor( - markingClassVisitor)))); - } + // TODO: disabled for now, see comment above. + // Methods without editable optimization info, for + // which we can't mark side-effects or escaping + // parameters, so we can save some effort. + //new AllAttributeVisitor( + //new DebugAttributeVisitor("Marking fields", + //new MultiAttributeVisitor( + // partialEvaluator, + // instructionUsageMarker, + // new AllInstructionVisitor( + // instructionUsageMarker.necessaryInstructionFilter( + // readWriteFieldMarker))))) + )); + } + })))); if (methodMarkingSynchronized) { @@ -685,7 +702,7 @@ new SimpleEnumDescriptorSimplifier()); // Update references to class members with simple enum classes. - programClassPool.classesAccept(new MemberReferenceFixer()); + programClassPool.classesAccept(new MemberReferenceFixer(configuration.android)); } } } @@ -747,7 +764,7 @@ { // We'll create values to be stored with fields, method parameters, // and return values. - ValueFactory valueFactory = new ParticularValueFactory(); + ValueFactory valueFactory = new RangeValueFactory(); ValueFactory detailedValueFactory = new DetailedArrayValueFactory(); InvocationUnit storingInvocationUnit = @@ -796,6 +813,20 @@ new ParallelAllClassVisitor( fillingOutValuesClassVisitor))); + if (configuration.assumeValues != null) + { + // Create a visitor for setting assumed values. + ClassPoolVisitor classPoolVisitor = + new AssumeClassSpecificationVisitorFactory(valueFactory) + .createClassPoolVisitor(configuration.assumeValues, + null, + new MultiMemberVisitor()); + + // Set the assumed values. + programClassPool.accept(classPoolVisitor); + libraryClassPool.accept(classPoolVisitor); + } + if (fieldPropagationValue) { // Count the constant fields. @@ -953,7 +984,7 @@ { // Fix all references to class members. // This operation also updates the stack sizes. - programClassPool.classesAccept(new MemberReferenceFixer()); + programClassPool.classesAccept(new MemberReferenceFixer(configuration.android)); // Remove unused bootstrap method arguments. programClassPool.classesAccept( @@ -1012,7 +1043,7 @@ new DuplicateInitializerInvocationFixer(addedCounter)))); // Fix all references to tweaked initializers. - programClassPool.classesAccept(new MemberReferenceFixer()); + programClassPool.classesAccept(new MemberReferenceFixer(configuration.android)); } } @@ -1051,6 +1082,7 @@ new BackwardBranchMarker(), new AccessMethodMarker(), new SynchronizedBlockMethodMarker(), + new FinalFieldAssignmentMarker(), new NonEmptyStackReturnMarker(stackSizeComputer) )) ))))), @@ -1135,7 +1167,7 @@ // in case they aren't shrunk later on. programClassPool.classesAccept(new RetargetedClassFilter(null, new TargetClassChanger())); programClassPool.classesAccept(new RetargetedClassFilter(null, new ClassReferenceFixer(true))); - programClassPool.classesAccept(new RetargetedClassFilter(null, new MemberReferenceFixer())); + programClassPool.classesAccept(new RetargetedClassFilter(null, new MemberReferenceFixer(configuration.android))); if (configuration.allowAccessModification) { @@ -1168,7 +1200,7 @@ new DuplicateInitializerInvocationFixer(addedCounter)))); // Fix all references to tweaked initializers. - programClassPool.classesAccept(new MemberReferenceFixer()); + programClassPool.classesAccept(new MemberReferenceFixer(configuration.android)); } } diff -Nru proguard-6.0.3/core/src/proguard/optimize/ParameterShrinker.java proguard-6.2.0/core/src/proguard/optimize/ParameterShrinker.java --- proguard-6.0.3/core/src/proguard/optimize/ParameterShrinker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/ParameterShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/BranchTargetFinder.java proguard-6.2.0/core/src/proguard/optimize/peephole/BranchTargetFinder.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/BranchTargetFinder.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/BranchTargetFinder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/ClassFinalizer.java proguard-6.2.0/core/src/proguard/optimize/peephole/ClassFinalizer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/ClassFinalizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/ClassFinalizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/ClassMerger.java proguard-6.2.0/core/src/proguard/optimize/peephole/ClassMerger.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/ClassMerger.java 2018-05-06 20:26:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/ClassMerger.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -154,7 +154,7 @@ // Don't merge classes that must be preserved. !KeepMarker.isKept(programClass) && - !KeepMarker.isKept(targetClass) && + !KeepMarker.isKept(targetClass) && // Only merge classes that haven't been retargeted yet. getTargetClass(programClass) == null && @@ -283,6 +283,13 @@ !shadowsAnyMethods(programClass, targetClass) && !shadowsAnyMethods(targetClass, programClass) && + (!DETAILS || print(programClass, "No type variables/parameterized types?")) && + + // The two classes must not have a signature attribute as type variables + // and/or parameterized types can not always be merged. + !hasSignatureAttribute(programClass) && + !hasSignatureAttribute(targetClass) && + (!DETAILS || print(programClass, "No non-copiable attributes?")) && // The class to be merged into the target class must not have @@ -519,6 +526,22 @@ /** + * Returns whether the given class has a Signature attributes containing + * type variables or parameterized types. + */ + private boolean hasSignatureAttribute(Clazz clazz) + { + AttributeCounter counter = new AttributeCounter(); + + clazz.attributesAccept( + new AttributeNameFilter( + new FixedStringMatcher(ClassConstants.ATTR_Signature), + counter)); + + return counter.getCount() > 0; + } + + /** * Returns whether the two given classes have fields with the same * names and descriptors. */ diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java proguard-6.2.0/core/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/GotoGotoReplacer.java proguard-6.2.0/core/src/proguard/optimize/peephole/GotoGotoReplacer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/GotoGotoReplacer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/GotoGotoReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/GotoReturnReplacer.java proguard-6.2.0/core/src/proguard/optimize/peephole/GotoReturnReplacer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/GotoReturnReplacer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/GotoReturnReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/HorizontalClassMerger.java proguard-6.2.0/core/src/proguard/optimize/peephole/HorizontalClassMerger.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/HorizontalClassMerger.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/HorizontalClassMerger.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/InstructionSequenceConstants.java proguard-6.2.0/core/src/proguard/optimize/peephole/InstructionSequenceConstants.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/InstructionSequenceConstants.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/InstructionSequenceConstants.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/InstructionSequenceReplacer.java proguard-6.2.0/core/src/proguard/optimize/peephole/InstructionSequenceReplacer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/InstructionSequenceReplacer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/InstructionSequenceReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/InstructionSequencesReplacer.java proguard-6.2.0/core/src/proguard/optimize/peephole/InstructionSequencesReplacer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/InstructionSequencesReplacer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/InstructionSequencesReplacer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/LineNumberLinearizer.java proguard-6.2.0/core/src/proguard/optimize/peephole/LineNumberLinearizer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/LineNumberLinearizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/LineNumberLinearizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/MemberPrivatizer.java proguard-6.2.0/core/src/proguard/optimize/peephole/MemberPrivatizer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/MemberPrivatizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/MemberPrivatizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/MethodFinalizer.java proguard-6.2.0/core/src/proguard/optimize/peephole/MethodFinalizer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/MethodFinalizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/MethodFinalizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/MethodInliner.java proguard-6.2.0/core/src/proguard/optimize/peephole/MethodInliner.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/MethodInliner.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/MethodInliner.java 2019-10-04 12:07:45.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -39,6 +39,10 @@ * This AttributeVisitor inlines short methods or methods that are only invoked * once, in the code attributes that it visits. * + * @see SuperInvocationMarker + * @see BackwardBranchMarker + * @see AccessMethodMarker + * @see SideEffectClassMarker * @author Eric Lafortune */ public class MethodInliner @@ -59,9 +63,11 @@ static final int INLINED_METHOD_END_LINE_NUMBER = -1; //* - private static final boolean DEBUG = false; + private static final boolean DEBUG = false; + private static final boolean DEBUG_DETAILS = false; /*/ - public static boolean DEBUG = System.getProperty("mi") != null; + public static boolean DEBUG = System.getProperty("mi") != null; + public static boolean DEBUG_DETAILS = System.getProperty("mid") != null; //*/ @@ -107,7 +113,7 @@ * @param microEdition indicates whether the resulting code is * targeted at Java Micro Edition. * @param android indicates whether the resulting code is - * targeted at the androidVM. + * targeted at the Dalvik VM. * @param allowAccessModification indicates whether the access modifiers of * classes and class members can be changed * in order to inline methods. @@ -303,7 +309,6 @@ (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0; // Count the number of parameters, taking into account their categories. - int parameterCount = ClassUtil.internalMethodParameterCount(descriptor); int parameterSize = ClassUtil.internalMethodParameterSize(descriptor); int parameterOffset = isStatic ? 0 : 1; @@ -584,9 +589,18 @@ { int accessFlags = programMethod.getAccessFlags(); + if (DEBUG_DETAILS) + { + System.out.println("MethodInliner: checking ["+ + programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] in ["+ + targetClass.getName()+"."+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]"); + } + if (// Don't inline methods that must be preserved. !KeepMarker.isKept(programMethod) && + DEBUG("Access?") && + // Only inline the method if it is private, static, or final. // This currently precludes default interface methods, because // they can't be final. @@ -594,11 +608,15 @@ ClassConstants.ACC_STATIC | ClassConstants.ACC_FINAL)) != 0 && + DEBUG("Synchronized?") && + // Only inline the method if it is not synchronized, etc. (accessFlags & (ClassConstants.ACC_SYNCHRONIZED | ClassConstants.ACC_NATIVE | ClassConstants.ACC_ABSTRACT)) == 0 && + DEBUG("Init?") && + // Don't inline an method, except in an method in the // same class. // (!programMethod.getName(programClass).equals(ClassConstants.METHOD_NAME_INIT) || @@ -606,29 +624,41 @@ // targetMethod.getName(targetClass).equals(ClassConstants.METHOD_NAME_INIT))) && !programMethod.getName(programClass).equals(ClassConstants.METHOD_NAME_INIT) && + DEBUG("Self?") && + // Don't inline a method into itself. (!programMethod.equals(targetMethod) || !programClass.equals(targetClass)) && + DEBUG("Recurse?") && + // Only inline the method if it isn't recursing. !inliningMethods.contains(programMethod) && + DEBUG("Version?") && + // Only inline the method if its target class has at least the // same version number as the source class, in order to avoid // introducing incompatible constructs. targetClass.u4version >= programClass.u4version && + DEBUG("Super?") && + // Only inline the method if it doesn't invoke a super method or a // dynamic method, or if it is in the same class. (!SuperInvocationMarker.invokesSuperMethods(programMethod) && !DynamicInvocationMarker.invokesDynamically(programMethod) || programClass.equals(targetClass)) && + DEBUG("Branch?") && + // Only inline the method if it doesn't branch backward while there // are uninitialized objects. (!BackwardBranchMarker.branchesBackward(programMethod) || uninitializedObjectCount == 0) && + DEBUG("Access private?") && + // Only inline if the code access of the inlined method allows it. (allowAccessModification || ((!AccessMethodMarker.accessesPrivateCode(programMethod) || @@ -638,12 +668,24 @@ ClassUtil.internalPackageName(programClass.getName()).equals( ClassUtil.internalPackageName(targetClass.getName()))))) && -// (!AccessMethodMarker.accessesProtectedCode(programMethod) || -// targetClass.extends_(programClass) || -// targetClass.implements_(programClass)) || + DEBUG("Access private in subclass?") && + + // Only inline a method from a superclass if it doesn't access + // private code (with invokespecial), because we can't fix the + // invocation. (test2172) [DGD-1258] + (!AccessMethodMarker.accessesPrivateCode(programMethod) || + programClass.equals(targetClass) || + !targetClass.extendsOrImplements(programClass)) && + + DEBUG("Access protected?") && + + // Only inline code that accesses protected code into the same + // class. (!AccessMethodMarker.accessesProtectedCode(programMethod) || programClass.equals(targetClass)) && + DEBUG("Synchronization?") && + // if the method to be inlined has a synchronized block only inline it into // the target method if its invocation is covered by a catchall handler or // none at all. This might happen if the target method has been obfuscated @@ -651,15 +693,29 @@ (!SynchronizedBlockMethodMarker.hasSynchronizedBlock(programMethod) || coveredByCatchAllHandler) && + DEBUG("Final fields?") && + + // Methods assigning final fields cannot be inlined, at least on Android + // this leads to VerifyErrors at runtime. + // This should normally not happen anyways, but some tools modify/generate + // bytecode that would lead to such situations, e.g. jacoco, see DGD-561. + !FinalFieldAssignmentMarker.assignsFinalField(programMethod) && + + DEBUG("Catch?") && + // Only inline the method if it doesn't catch exceptions, or if it // is invoked with an empty stack. (!CatchExceptionMarker.catchesExceptions(programMethod) || emptyInvokingStack) && + DEBUG("Stack?") && + // Only inline the method if it always returns with an empty // stack. !NonEmptyStackReturnMarker.returnsWithNonEmptyStack(programMethod) && + DEBUG("Side effects?") && + // Only inline the method if its related static initializers don't // have any side effects. !SideEffectClassChecker.mayHaveSideEffects(targetClass, @@ -732,6 +788,19 @@ } } + /** + * Returns true, while printing out the given debug message. + */ + private boolean DEBUG(String string) + { + if (DEBUG_DETAILS) + { + System.out.println(" "+string); + } + + return true; + } + // Implementations for ExceptionInfoVisitor. diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/NopRemover.java proguard-6.2.0/core/src/proguard/optimize/peephole/NopRemover.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/NopRemover.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/NopRemover.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/PeepholeOptimizer.java proguard-6.2.0/core/src/proguard/optimize/peephole/PeepholeOptimizer.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/PeepholeOptimizer.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/PeepholeOptimizer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/ReachableCodeMarker.java proguard-6.2.0/core/src/proguard/optimize/peephole/ReachableCodeMarker.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/ReachableCodeMarker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/ReachableCodeMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/RetargetedClassFilter.java proguard-6.2.0/core/src/proguard/optimize/peephole/RetargetedClassFilter.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/RetargetedClassFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/RetargetedClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java proguard-6.2.0/core/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/TargetClassChanger.java proguard-6.2.0/core/src/proguard/optimize/peephole/TargetClassChanger.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/TargetClassChanger.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/TargetClassChanger.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/UnreachableCodeRemover.java proguard-6.2.0/core/src/proguard/optimize/peephole/UnreachableCodeRemover.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/UnreachableCodeRemover.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/UnreachableCodeRemover.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/UnreachableExceptionRemover.java proguard-6.2.0/core/src/proguard/optimize/peephole/UnreachableExceptionRemover.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/UnreachableExceptionRemover.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/UnreachableExceptionRemover.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/VariableShrinker.java proguard-6.2.0/core/src/proguard/optimize/peephole/VariableShrinker.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/VariableShrinker.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/VariableShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/VerticalClassMerger.java proguard-6.2.0/core/src/proguard/optimize/peephole/VerticalClassMerger.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/VerticalClassMerger.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/VerticalClassMerger.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/WildcardConstantFilter.java proguard-6.2.0/core/src/proguard/optimize/peephole/WildcardConstantFilter.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/WildcardConstantFilter.java 2018-01-28 00:15:20.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/WildcardConstantFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -100,6 +100,15 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + if (!containsWildcard(clazz, dynamicConstant)) + { + constantVisitor.visitDynamicConstant(clazz, dynamicConstant); + } + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { if (!containsWildcard(clazz, invokeDynamicConstant)) diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/WrapperClassMerger.java proguard-6.2.0/core/src/proguard/optimize/peephole/WrapperClassMerger.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/WrapperClassMerger.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/WrapperClassMerger.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/peephole/WrapperClassUseSimplifier.java proguard-6.2.0/core/src/proguard/optimize/peephole/WrapperClassUseSimplifier.java --- proguard-6.0.3/core/src/proguard/optimize/peephole/WrapperClassUseSimplifier.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/peephole/WrapperClassUseSimplifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/TailRecursionSimplifier.java proguard-6.2.0/core/src/proguard/optimize/TailRecursionSimplifier.java --- proguard-6.0.3/core/src/proguard/optimize/TailRecursionSimplifier.java 2018-01-24 21:49:28.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/TailRecursionSimplifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/optimize/WriteOnlyFieldFilter.java proguard-6.2.0/core/src/proguard/optimize/WriteOnlyFieldFilter.java --- proguard-6.0.3/core/src/proguard/optimize/WriteOnlyFieldFilter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/optimize/WriteOnlyFieldFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/OutputWriter.java proguard-6.2.0/core/src/proguard/OutputWriter.java --- proguard-6.0.3/core/src/proguard/OutputWriter.java 2018-02-01 21:55:37.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/OutputWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ParseException.java proguard-6.2.0/core/src/proguard/ParseException.java --- proguard-6.0.3/core/src/proguard/ParseException.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ParseException.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/preverify/CodePreverifier.java proguard-6.2.0/core/src/proguard/preverify/CodePreverifier.java --- proguard-6.0.3/core/src/proguard/preverify/CodePreverifier.java 2018-05-03 13:36:34.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/preverify/CodePreverifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -287,21 +287,27 @@ int maximumVariablesSize = variables.size(); int typeIndex = 0; - // Count the the number of verification types, ignoring any nulls at - // the end. + // Count the the number of verification types, ignoring any nulls + // at the end. for (int index = 0; index < maximumVariablesSize; index++) { Value value = variables.getValue(index); typeIndex++; - // Remember the maximum live type index. + // Remember the maximum live type (or uninitialized "this" + // type) index. A dead uninitialized "this" is not possible in + // plain Java code, but it is possible in optimized code and + // in other languages like Kotlin (in exception handlers). + // It has to be marked too ("flagThisUninit" in the JVM specs). if (value != null && - livenessAnalyzer.isAliveBefore(offset, index)) + (livenessAnalyzer.isAliveBefore(offset, index) || + isUninitalizedThis(offset, index))) { typeCount = typeIndex; - // Category 2 types that are alive are stored as single entries. + // Category 2 types that are alive are stored as single + // entries. if (value.isCategory2()) { index++; @@ -325,9 +331,11 @@ // Fill out the type. VerificationType type; + // Is the value not null and alive (or uninitialized "this")? if (value != null && (offset == AT_METHOD_ENTRY || - livenessAnalyzer.isAliveBefore(offset, index))) + livenessAnalyzer.isAliveBefore(offset, index) || + isUninitalizedThis(offset, index))) { type = correspondingVerificationType(programClass, programMethod, @@ -466,24 +474,23 @@ if (instructionOffsetValue.instructionOffsetCount() == 1) { + // Is it a method parameter? if (instructionOffsetValue.isMethodParameter(0)) { - // Are we in an instance initialization method, - // before the super initialization, loading "this"? - if (instructionOffsetValue.methodParameter(0) == 0 && - initializationFinder.isInitializer() && - offset <= initializationFinder.superInitializationOffset()) + // Is the parameter an uninitialized "this"? + if (isUninitalizedThis(offset, + instructionOffsetValue.methodParameter(0))) { // It's an UninitializedThis type. return VerificationTypeFactory.createUninitializedThisType(); } } + // Is it a newly created instance? else if (instructionOffsetValue.isNewinstance(0)) { int producerOffset = instructionOffsetValue.instructionOffset(0); - // Is the reference type newly created and still - // uninitialized? + // Is it still uninitialized? if (!initializationFinder.isInitializedBefore(offset, instructionOffsetValue)) { // It's an Uninitialized type. @@ -633,6 +640,19 @@ } + /** + * Returns wheter the specified variable is an uninitialized "this" at the + * given instruction offset. + */ + private boolean isUninitalizedThis(int offset, int variableIndex) + { + return + variableIndex == 0 && + initializationFinder.isInitializer() && + offset <= initializationFinder.superInitializationOffset(); + } + + /** * Returns whether the given instruction opcode represents a dup or swap * instruction (dup, dup_x1, dup_x2, dup2, dup2_x1, dup2_x2, swap). diff -Nru proguard-6.0.3/core/src/proguard/preverify/CodeSubroutineInliner.java proguard-6.2.0/core/src/proguard/preverify/CodeSubroutineInliner.java --- proguard-6.0.3/core/src/proguard/preverify/CodeSubroutineInliner.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/preverify/CodeSubroutineInliner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/preverify/Preverifier.java proguard-6.2.0/core/src/proguard/preverify/Preverifier.java --- proguard-6.0.3/core/src/proguard/preverify/Preverifier.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/preverify/Preverifier.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/preverify/SubroutineInliner.java proguard-6.2.0/core/src/proguard/preverify/SubroutineInliner.java --- proguard-6.0.3/core/src/proguard/preverify/SubroutineInliner.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/preverify/SubroutineInliner.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/ProGuard.java proguard-6.2.0/core/src/proguard/ProGuard.java --- proguard-6.0.3/core/src/proguard/ProGuard.java 2018-05-06 20:34:21.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/ProGuard.java 2019-10-04 12:15:32.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -29,6 +29,7 @@ import proguard.configuration.ConfigurationLoggingAdder; import proguard.obfuscate.Obfuscator; import proguard.optimize.Optimizer; +import proguard.optimize.gson.GsonOptimizer; import proguard.optimize.peephole.LineNumberLinearizer; import proguard.preverify.*; import proguard.shrink.Shrinker; @@ -43,7 +44,7 @@ */ public class ProGuard { - public static final String VERSION = "ProGuard, version 6.0.3"; + public static final String VERSION = "ProGuard, version 6.2.0"; private final Configuration configuration; private ClassPool programClassPool = new ClassPool(); @@ -145,6 +146,16 @@ shrink(); } + StringMatcher filter = configuration.optimizations != null ? + new ListParser(new NameParser()).parse(configuration.optimizations) : + new ConstantMatcher(true); + + if (configuration.optimize && + filter.matches(Optimizer.LIBRARY_GSON)) + { + optimizeGson(); + } + if (configuration.optimize) { for (int optimizationPass = 0; @@ -399,6 +410,26 @@ /** + * Optimizes usages of the Gson library. + */ + private void optimizeGson() throws IOException + { + if (programClassPool.getClass("com/google/gson/Gson") != null) + { + if (configuration.verbose) + { + System.out.println("Optimizing usages of Gson library..."); + } + + new GsonOptimizer().execute(programClassPool, + libraryClassPool, + injectedClassNameMap, + configuration); + } + } + + + /** * Performs the optimization step. */ private boolean optimize(int currentPass, @@ -424,18 +455,6 @@ if (configuration.verbose) { System.out.println("Obfuscating..."); - - // We'll apply a mapping, if requested. - if (configuration.applyMapping != null) - { - System.out.println("Applying mapping [" + PrintWriterUtil.fileName(configuration.applyMapping) + "]"); - } - - // We'll print out the mapping, if requested. - if (configuration.printMapping != null) - { - System.out.println("Printing mapping to [" + PrintWriterUtil.fileName(configuration.printMapping) + "]..."); - } } // Perform the actual obfuscation. diff -Nru proguard-6.0.3/core/src/proguard/SeedPrinter.java proguard-6.2.0/core/src/proguard/SeedPrinter.java --- proguard-6.0.3/core/src/proguard/SeedPrinter.java 2018-01-14 23:15:18.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/SeedPrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -57,7 +57,7 @@ // Check if we have at least some keep commands. if (configuration.keep == null) { - throw new IOException("You have to specify '-keep' options for the shrinking step."); + throw new IOException("You have to specify '-keep' options if you want to write out kept elements with '-printseeds'."); } // Clean up any old visitor info. diff -Nru proguard-6.0.3/core/src/proguard/shrink/AnnotationUsageMarker.java proguard-6.2.0/core/src/proguard/shrink/AnnotationUsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/AnnotationUsageMarker.java 2018-05-06 20:26:14.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/AnnotationUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/shrink/ClassShrinker.java proguard-6.2.0/core/src/proguard/shrink/ClassShrinker.java --- proguard-6.0.3/core/src/proguard/shrink/ClassShrinker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/ClassShrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -50,8 +50,11 @@ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE]; private int[] bootstrapMethodIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE]; + private final MyNestmemberShrinker nestMemberShrinker = new MyNestmemberShrinker(); private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper(); private final BootstrapMethodRemapper bootstrapMethodRemapper = new BootstrapMethodRemapper(); + private final MySignatureCleaner signatureCleaner = new MySignatureCleaner(); + /** @@ -79,7 +82,10 @@ .visitProgramClass(programClass); } - // Shrinking the constant pool also sets up an index map. + // Shrink the arrays for nest members. + programClass.attributesAccept(nestMemberShrinker); + + // Shrink the constant pool, also setting up an index map. int newConstantPoolCount = shrinkConstantPool(programClass.constantPool, programClass.u2constantPoolCount); @@ -123,7 +129,6 @@ } // Replace any unused classes in the signatures. - MySignatureCleaner signatureCleaner = new MySignatureCleaner(); programClass.fieldsAccept(new AllAttributeVisitor(signatureCleaner)); programClass.methodsAccept(new AllAttributeVisitor(signatureCleaner)); programClass.attributesAccept(signatureCleaner); @@ -280,6 +285,29 @@ } + /** + * This AttributeVisitor shrinks the nest members in the nest member + * attributes that it visits. + */ + private class MyNestmemberShrinker + extends SimplifiedVisitor + implements AttributeVisitor + { + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + // Shrink the array of nest member indices. + // We must do this before the corresponding constants are remapped. + nestMembersAttribute.u2classesCount = + shrinkConstantIndexArray(((ProgramClass)clazz).constantPool, + nestMembersAttribute.u2classes, + nestMembersAttribute.u2classesCount); + } + } + + /** * This AttributeVisitor updates the Utf8 constants of signatures * of classes, fields, and methods. diff -Nru proguard-6.0.3/core/src/proguard/shrink/InnerUsageMarker.java proguard-6.2.0/core/src/proguard/shrink/InnerUsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/InnerUsageMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/InnerUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -45,7 +45,7 @@ { private final UsageMarker usageMarker; - // Fields acting as a return parameters for several methods. + // Fields acting as return parameters for several methods. private boolean attributeUsed; private boolean classUsed; diff -Nru proguard-6.0.3/core/src/proguard/shrink/InterfaceUsageMarker.java proguard-6.2.0/core/src/proguard/shrink/InterfaceUsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/InterfaceUsageMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/InterfaceUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/shrink/LocalVariableTypeUsageMarker.java proguard-6.2.0/core/src/proguard/shrink/LocalVariableTypeUsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/LocalVariableTypeUsageMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/LocalVariableTypeUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/shrink/NestUsageMarker.java proguard-6.2.0/core/src/proguard/shrink/NestUsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/NestUsageMarker.java 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/NestUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,160 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.shrink; + +import proguard.classfile.*; +import proguard.classfile.attribute.*; +import proguard.classfile.attribute.visitor.*; +import proguard.classfile.constant.*; +import proguard.classfile.constant.visitor.ConstantVisitor; +import proguard.classfile.util.SimplifiedVisitor; +import proguard.classfile.visitor.ClassVisitor; + +/** + * This AttributeVisitor marks all necessary nest host attributes and nest + * members attributes that it visits. + * + * @see UsageMarker + * + * @author Eric Lafortune + */ +public class NestUsageMarker +extends SimplifiedVisitor +implements AttributeVisitor, + ConstantVisitor, + ClassVisitor +{ + private final UsageMarker usageMarker; + + // Fields acting as return parameters for several methods. + private boolean attributeUsed; + private boolean classUsed; + + + /** + * Creates a new NestUsageMarker. + * @param usageMarker the usage marker that is used to mark the classes + * and class members. + */ + public NestUsageMarker(UsageMarker usageMarker) + { + this.usageMarker = usageMarker; + } + + + // Implementations for AttributeVisitor. + + public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} + + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + // Mark the necessary nest host class constant. + attributeUsed = false; + clazz.constantPoolEntryAccept(nestHostAttribute.u2hostClassIndex, this); + + if (attributeUsed) + { + // We got a positive used flag, so the nest host class is being used. + // Mark this attribute as being used as well. + usageMarker.markAsUsed(nestHostAttribute); + + markConstant(clazz, nestHostAttribute.u2attributeNameIndex); + } + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + // Mark the necessary inner classes information. + attributeUsed = false; + nestMembersAttribute.memberClassConstantsAccept(clazz, this); + + if (attributeUsed) + { + // We got a positive used flag, so the nest members class is being used. + // Mark this attribute as being used as well. + usageMarker.markAsUsed(nestMembersAttribute); + + markConstant(clazz, nestMembersAttribute.u2attributeNameIndex); + } + } + + + // Implementations for ConstantVisitor. + + public void visitClassConstant(Clazz clazz, ClassConstant classConstant) + { + classUsed = usageMarker.isUsed(classConstant); + + // Is the class constant marked as being used? + if (!classUsed) + { + // Check the referenced class. + classUsed = true; + classConstant.referencedClassAccept(this); + + // Is the referenced class marked as being used? + if (classUsed) + { + // Mark the class constant and its Utf8 constant. + usageMarker.markAsUsed(classConstant); + + markConstant(clazz, classConstant.u2nameIndex); + } + } + + // The return value. + attributeUsed |= classUsed; + } + + + public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) + { + usageMarker.markAsUsed(utf8Constant); + } + + + // Implementations for ClassVisitor. + + public void visitProgramClass(ProgramClass programClass) + { + classUsed = usageMarker.isUsed(programClass); + } + + + public void visitLibraryClass(LibraryClass libraryClass) + { + classUsed = true; + } + + + // Small utility methods. + + /** + * Marks the given constant pool entry of the given class. This includes + * visiting any other referenced constant pool entries. + */ + private void markConstant(Clazz clazz, int index) + { + clazz.constantPoolEntryAccept(index, this); + } +} diff -Nru proguard-6.0.3/core/src/proguard/shrink/ShortestUsageMarker.java proguard-6.2.0/core/src/proguard/shrink/ShortestUsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/ShortestUsageMarker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/ShortestUsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/shrink/ShortestUsageMark.java proguard-6.2.0/core/src/proguard/shrink/ShortestUsageMark.java --- proguard-6.0.3/core/src/proguard/shrink/ShortestUsageMark.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/ShortestUsageMark.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/shrink/ShortestUsagePrinter.java proguard-6.2.0/core/src/proguard/shrink/ShortestUsagePrinter.java --- proguard-6.0.3/core/src/proguard/shrink/ShortestUsagePrinter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/ShortestUsagePrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -26,7 +26,7 @@ import proguard.classfile.util.*; import proguard.classfile.visitor.*; -import java.io.PrintStream; +import java.io.PrintWriter; /** @@ -45,46 +45,23 @@ { private final ShortestUsageMarker shortestUsageMarker; private final boolean verbose; - private final PrintStream ps; + private final PrintWriter pw; /** - * Creates a new UsagePrinter that prints verbosely to System.out. - * @param shortestUsageMarker the usage marker that was used to mark the - * classes and class members. - */ - public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker) - { - this(shortestUsageMarker, true); - } - - - /** - * Creates a new UsagePrinter that prints to the given stream. - * @param shortestUsageMarker the usage marker that was used to mark the - * classes and class members. - * @param verbose specifies whether the output should be verbose. - */ - public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker, - boolean verbose) - { - this(shortestUsageMarker, verbose, System.out); - } - - /** * Creates a new UsagePrinter that prints to the given stream. * @param shortestUsageMarker the usage marker that was used to mark the * classes and class members. * @param verbose specifies whether the output should be verbose. - * @param printStream the stream to which to print. + * @param printWriter the writer to which to print. */ public ShortestUsagePrinter(ShortestUsageMarker shortestUsageMarker, boolean verbose, - PrintStream printStream) + PrintWriter printWriter) { this.shortestUsageMarker = shortestUsageMarker; this.verbose = verbose; - this.ps = printStream; + this.pw = printWriter; } @@ -93,7 +70,7 @@ public void visitProgramClass(ProgramClass programClass) { // Print the name of this class. - ps.println(ClassUtil.externalClassName(programClass.getName())); + pw.println(ClassUtil.externalClassName(programClass.getName())); // Print the reason for keeping this class. printReason(programClass); @@ -103,10 +80,10 @@ public void visitLibraryClass(LibraryClass libraryClass) { // Print the name of this class. - ps.println(ClassUtil.externalClassName(libraryClass.getName())); + pw.println(ClassUtil.externalClassName(libraryClass.getName())); // Print the reason for keeping this class. - ps.println(" is a library class.\n"); + pw.println(" is a library class.\n"); } @@ -118,7 +95,7 @@ String name = programField.getName(programClass); String type = programField.getDescriptor(programClass); - ps.println(ClassUtil.externalClassName(programClass.getName()) + + pw.println(ClassUtil.externalClassName(programClass.getName()) + (verbose ? ": " + ClassUtil.externalFullFieldDescription(0, name, type): "." + name)); @@ -134,12 +111,12 @@ String name = programMethod.getName(programClass); String type = programMethod.getDescriptor(programClass); - ps.print(ClassUtil.externalClassName(programClass.getName()) + + pw.print(ClassUtil.externalClassName(programClass.getName()) + (verbose ? ": " + ClassUtil.externalFullMethodDescription(programClass.getName(), 0, name, type): "." + name)); programMethod.attributesAccept(programClass, this); - ps.println(); + pw.println(); // Print the reason for keeping this method. printReason(programMethod); @@ -152,13 +129,13 @@ String name = libraryField.getName(libraryClass); String type = libraryField.getDescriptor(libraryClass); - ps.println(ClassUtil.externalClassName(libraryClass.getName()) + + pw.println(ClassUtil.externalClassName(libraryClass.getName()) + (verbose ? ": " + ClassUtil.externalFullFieldDescription(0, name, type): "." + name)); // Print the reason for keeping this field. - ps.println(" is a library field.\n"); + pw.println(" is a library field.\n"); } @@ -168,13 +145,13 @@ String name = libraryMethod.getName(libraryClass); String type = libraryMethod.getDescriptor(libraryClass); - ps.println(ClassUtil.externalClassName(libraryClass.getName()) + + pw.println(ClassUtil.externalClassName(libraryClass.getName()) + (verbose ? ": " + ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, name, type): "." + name)); // Print the reason for keeping this method. - ps.println(" is a library method.\n"); + pw.println(" is a library method.\n"); } @@ -191,7 +168,7 @@ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) { - ps.print(" (" + + pw.print(" (" + lineNumberTableAttribute.getLowestLineNumber() + ":" + lineNumberTableAttribute.getHighestLineNumber() + ")"); } @@ -206,7 +183,7 @@ ShortestUsageMark shortestUsageMark = shortestUsageMarker.getShortestUsageMark(visitorAccepter); // Print the reason for keeping this class. - ps.print(" " + shortestUsageMark.getReason()); + pw.print(" " + shortestUsageMark.getReason()); // Print the class or method that is responsible, with its reasons. shortestUsageMark.acceptClassVisitor(this); @@ -214,7 +191,7 @@ } else { - ps.println(" is not being kept.\n"); + pw.println(" is not being kept.\n"); } } } diff -Nru proguard-6.0.3/core/src/proguard/shrink/Shrinker.java proguard-6.2.0/core/src/proguard/shrink/Shrinker.java --- proguard-6.0.3/core/src/proguard/shrink/Shrinker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/Shrinker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -24,6 +24,7 @@ import proguard.classfile.*; import proguard.classfile.attribute.visitor.*; import proguard.classfile.visitor.*; +import proguard.util.PrintWriterUtil; import java.io.*; @@ -58,6 +59,10 @@ throw new IOException("You have to specify '-keep' options for the shrinking step."); } + // We're using the system's default character encoding for writing to + // the standard output. + PrintWriter out = new PrintWriter(System.out, true); + // Clean up any old visitor info. programClassPool.classesAccept(new ClassCleaner()); libraryClassPool.classesAccept(new ClassCleaner()); @@ -70,13 +75,12 @@ // Automatically mark the parameterless constructors of seed classes, // mainly for convenience and for backward compatibility. ClassVisitor classUsageMarker = - new MultiClassVisitor(new ClassVisitor[] - { + new MultiClassVisitor( usageMarker, new NamedMethodVisitor(ClassConstants.METHOD_NAME_INIT, ClassConstants.METHOD_TYPE_INIT, usageMarker) - }); + ); ClassPoolVisitor classPoolvisitor = new KeepClassSpecificationVisitorFactory(true, false, false) @@ -91,29 +95,30 @@ libraryClassPool.accept(classPoolvisitor); libraryClassPool.classesAccept(usageMarker); - // Mark interfaces that have to be kept. - programClassPool.classesAccept(new InterfaceUsageMarker(usageMarker)); - // Mark the inner class and annotation information that has to be kept. programClassPool.classesAccept( new UsedClassFilter(usageMarker, new AllAttributeVisitor(true, - new MultiAttributeVisitor(new AttributeVisitor[] - { + new MultiAttributeVisitor( new InnerUsageMarker(usageMarker), + new NestUsageMarker(usageMarker), new AnnotationUsageMarker(usageMarker), new LocalVariableTypeUsageMarker(usageMarker) - })))); + )))); + + // Mark interfaces that have to be kept. + programClassPool.classesAccept(new InterfaceUsageMarker(usageMarker)); // Should we explain ourselves? if (configuration.whyAreYouKeeping != null) { - System.out.println(); + out.println(); // Create a visitor for explaining classes and class members. ShortestUsagePrinter shortestUsagePrinter = new ShortestUsagePrinter((ShortestUsageMarker)usageMarker, - configuration.verbose); + configuration.verbose, + out); ClassPoolVisitor whyClassPoolvisitor = new ClassSpecificationVisitorFactory() @@ -130,23 +135,19 @@ if (configuration.printUsage != null) { - PrintStream ps = - configuration.printUsage == Configuration.STD_OUT ? System.out : - new PrintStream( - new BufferedOutputStream( - new FileOutputStream(configuration.printUsage))); - - // Print out items that will be removed. - programClassPool.classesAcceptAlphabetically( - new UsagePrinter(usageMarker, true, ps)); + PrintWriter usageWriter = + PrintWriterUtil.createPrintWriterOut(configuration.printUsage); - if (ps == System.out) + try { - ps.flush(); + // Print out items that will be removed. + programClassPool.classesAcceptAlphabetically( + new UsagePrinter(usageMarker, true, usageWriter)); } - else + finally { - ps.close(); + PrintWriterUtil.closePrintWriter(configuration.printUsage, + usageWriter); } } @@ -172,9 +173,9 @@ if (configuration.verbose) { - System.out.println("Removing unused program classes and class elements..."); - System.out.println(" Original number of program classes: " + originalProgramClassPoolSize); - System.out.println(" Final number of program classes: " + newProgramClassPoolSize); + out.println("Removing unused program classes and class elements..."); + out.println(" Original number of program classes: " + originalProgramClassPoolSize); + out.println(" Final number of program classes: " + newProgramClassPoolSize); } if (newProgramClassPoolSize == 0 && diff -Nru proguard-6.0.3/core/src/proguard/shrink/UsageMarker.java proguard-6.2.0/core/src/proguard/shrink/UsageMarker.java --- proguard-6.0.3/core/src/proguard/shrink/UsageMarker.java 2018-02-03 20:15:06.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/UsageMarker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -102,10 +102,7 @@ markConstant(programClass, programClass.u2thisClass); // Mark the superclass. - if (programClass.u2superClass != 0) - { - markConstant(programClass, programClass.u2superClass); - } + markOptionalConstant(programClass, programClass.u2superClass); // Give the interfaces preliminary marks. programClass.hierarchyAccept(false, false, true, false, @@ -497,6 +494,23 @@ } + public void visitDynamicConstant(Clazz clazz, DynamicConstant dynamicConstant) + { + if (shouldBeMarkedAsUsed(dynamicConstant)) + { + markAsUsed(dynamicConstant); + + markConstant(clazz, dynamicConstant.u2nameAndTypeIndex); + + // Mark the referenced descriptor classes. + dynamicConstant.referencedClassesAccept(this); + + // Mark the bootstrap methods attribute. + clazz.attributesAccept(new MyBootStrapMethodUsageMarker(dynamicConstant.u2bootstrapMethodAttributeIndex)); + } + } + + public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant) { if (shouldBeMarkedAsUsed(invokeDynamicConstant)) @@ -715,13 +729,33 @@ { markAsUsed(enclosingMethodAttribute); - markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex); - markConstant(clazz, enclosingMethodAttribute.u2classIndex); + markConstant( clazz, enclosingMethodAttribute.u2attributeNameIndex); + markConstant( clazz, enclosingMethodAttribute.u2classIndex); + markOptionalConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); + } - if (enclosingMethodAttribute.u2nameAndTypeIndex != 0) - { - markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex); - } + + public void visitNestHostAttribute(Clazz clazz, NestHostAttribute nestHostAttribute) + { + // Don't mark the attribute and its contents yet. We may mark it later, + // in NestUsageMarker. + //markAsUsed(nestHostAttribute); + + //markConstant(clazz, nestHostAttribute.u2attributeNameIndex); + //markConstant(clazz, nestHostAttribute.u2hostClassIndex); + } + + + public void visitNestMembersAttribute(Clazz clazz, NestMembersAttribute nestMembersAttribute) + { + // Don't mark the attribute and its contents yet. We may mark it later, + // in NestUsageMarker. + //markAsUsed(nestMembersAttribute); + + //markConstant(clazz, nestMembersAttribute.u2attributeNameIndex); + + // Mark the nest member entries. + //nestMembersAttribute.memberClassConstantsAccept(clazz, this); } @@ -729,22 +763,18 @@ { markAsUsed(moduleAttribute); - markConstant(clazz, moduleAttribute.u2attributeNameIndex); - markConstant(clazz, moduleAttribute.u2moduleNameIndex); + markConstant( clazz, moduleAttribute.u2attributeNameIndex); + markConstant( clazz, moduleAttribute.u2moduleNameIndex); + markOptionalConstant(clazz, moduleAttribute.u2moduleVersionIndex); - if (moduleAttribute.u2moduleVersionIndex != 0) - { - markConstant(clazz, moduleAttribute.u2moduleVersionIndex); - } + // Mark the constant pool entries referenced by the contained info. moduleAttribute.requiresAccept(clazz, this); moduleAttribute.exportsAccept(clazz, this); moduleAttribute.opensAccept(clazz, this); - for (int index = 0; index < moduleAttribute.u2usesCount; index++) - { - markConstant(clazz, moduleAttribute.u2uses[index]); - } + markConstants(clazz, moduleAttribute.u2uses, moduleAttribute.u2usesCount); + // Mark the constant pool entries referenced by the provides info. moduleAttribute.providesAccept(clazz, this); } @@ -763,6 +793,8 @@ markAsUsed(modulePackagesAttribute); markConstant(clazz, modulePackagesAttribute.u2attributeNameIndex); + + // Mark the constant pool entries referenced by the packages info. modulePackagesAttribute.packagesAccept(clazz, this); } @@ -943,10 +975,7 @@ { markAsUsed(exceptionInfo); - if (exceptionInfo.u2catchType != 0) - { - markConstant(clazz, exceptionInfo.u2catchType); - } + markOptionalConstant(clazz, exceptionInfo.u2catchType); } @@ -961,6 +990,7 @@ { markAsUsed(innerClassesInfo); + // Mark the constant pool entries referenced by the contained info. innerClassesInfo.innerClassConstantAccept(clazz, this); innerClassesInfo.outerClassConstantAccept(clazz, this); innerClassesInfo.innerNameConstantAccept(clazz, this); @@ -1036,8 +1066,8 @@ public void visitRequiresInfo(Clazz clazz, RequiresInfo requiresInfo) { - markConstant(clazz, requiresInfo.u2requiresIndex); - markConstant(clazz, requiresInfo.u2requiresVersionIndex); + markConstant( clazz, requiresInfo.u2requiresIndex); + markOptionalConstant(clazz, requiresInfo.u2requiresVersionIndex); } @@ -1045,12 +1075,8 @@ public void visitExportsInfo(Clazz clazz, ExportsInfo exportsInfo) { - markConstant(clazz, exportsInfo.u2exportsIndex); - - for (int index = 0; index < exportsInfo.u2exportsToCount; index++) - { - markConstant(clazz, exportsInfo.u2exportsToIndex[index]); - } + markConstant( clazz, exportsInfo.u2exportsIndex); + markConstants(clazz, exportsInfo.u2exportsToIndex, exportsInfo.u2exportsToCount); } @@ -1058,12 +1084,8 @@ public void visitOpensInfo(Clazz clazz, OpensInfo opensInfo) { - markConstant(clazz, opensInfo.u2opensIndex); - - for (int index = 0; index < opensInfo.u2opensToCount; index++) - { - markConstant(clazz, opensInfo.u2opensToIndex[index]); - } + markConstant( clazz, opensInfo.u2opensIndex); + markConstants(clazz, opensInfo.u2opensToIndex, opensInfo.u2opensToCount); } @@ -1071,12 +1093,8 @@ public void visitProvidesInfo(Clazz clazz, ProvidesInfo providesInfo) { - markConstant(clazz, providesInfo.u2providesIndex); - - for (int index = 0; index < providesInfo.u2providesWithCount; index++) - { - markConstant(clazz, providesInfo.u2providesWithIndex[index]); - } + markConstant( clazz, providesInfo.u2providesIndex); + markConstants(clazz, providesInfo.u2providesWithIndex, providesInfo.u2providesWithCount); } // // Implementations for AnnotationVisitor. @@ -1094,33 +1112,22 @@ // // public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) // { -// if (constantElementValue.u2elementNameIndex != 0) -// { -// markConstant(clazz, constantElementValue.u2elementNameIndex); -// } -// -// markConstant(clazz, constantElementValue.u2constantValueIndex); +// markOptionalConstant(clazz, constantElementValue.u2elementNameIndex); +// markConstant( clazz, constantElementValue.u2constantValueIndex); // } // // // public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) // { -// if (enumConstantElementValue.u2elementNameIndex != 0) -// { -// markConstant(clazz, enumConstantElementValue.u2elementNameIndex); -// } -// -// markConstant(clazz, enumConstantElementValue.u2typeNameIndex); -// markConstant(clazz, enumConstantElementValue.u2constantNameIndex); +// markOptionalConstant(clazz, enumConstantElementValue.u2elementNameIndex); +// markConstant( clazz, enumConstantElementValue.u2typeNameIndex); +// markConstant( clazz, enumConstantElementValue.u2constantNameIndex); // } // // // public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) // { -// if (classElementValue.u2elementNameIndex != 0) -// { -// markConstant(clazz, classElementValue.u2elementNameIndex); -// } +// markOptionalConstant(clazz, classElementValue.u2elementNameIndex); // // // Mark the referenced class constant pool entry. // markConstant(clazz, classElementValue.u2classInfoIndex); @@ -1129,10 +1136,7 @@ // // public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) // { -// if (annotationElementValue.u2elementNameIndex != 0) -// { -// markConstant(clazz, annotationElementValue.u2elementNameIndex); -// } +// markOptionalConstant(clazz, annotationElementValue.u2elementNameIndex); // // // Mark the constant pool entries referenced by the annotation. // annotationElementValue.annotationAccept(clazz, this); @@ -1141,10 +1145,7 @@ // // public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) // { -// if (arrayElementValue.u2elementNameIndex != 0) -// { -// markConstant(clazz, arrayElementValue.u2elementNameIndex); -// } +// markOptionalConstant(clazz, arrayElementValue.u2elementNameIndex); // // // Mark the constant pool entries referenced by the element values. // arrayElementValue.elementValuesAccept(clazz, annotation, this); @@ -1238,11 +1239,39 @@ /** - * Marks the given constant pool entry of the given class. This includes - * visiting any referenced objects. + * Marks the specified constant pool entries of the given class. + * This includes visiting any referenced objects. + */ + private void markConstants(Clazz clazz, + int[] constantIndices, + int constantIndicesCount) + { + for (int index = 0; index < constantIndicesCount; index++) + { + markConstant(clazz, constantIndices[index]); + } + } + + + /** + * Marks the specified constant pool entry of the given class, if the index + * is not 0. This includes visiting any referenced objects. + */ + private void markOptionalConstant(Clazz clazz, int constantIndex) + { + if (constantIndex != 0) + { + markConstant(clazz, constantIndex); + } + } + + + /** + * Marks the specified constant pool entry of the given class. + * This includes visiting any referenced objects. */ - private void markConstant(Clazz clazz, int index) + private void markConstant(Clazz clazz, int constantIndex) { - clazz.constantPoolEntryAccept(index, this); + clazz.constantPoolEntryAccept(constantIndex, this); } } diff -Nru proguard-6.0.3/core/src/proguard/shrink/UsagePrinter.java proguard-6.2.0/core/src/proguard/shrink/UsagePrinter.java --- proguard-6.0.3/core/src/proguard/shrink/UsagePrinter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/UsagePrinter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -26,7 +26,7 @@ import proguard.classfile.util.*; import proguard.classfile.visitor.*; -import java.io.PrintStream; +import java.io.PrintWriter; /** @@ -45,43 +45,28 @@ { private final UsageMarker usageMarker; private final boolean printUnusedItems; - private final PrintStream ps; + private final PrintWriter pw; // A field to remember the class name, if a header is needed for class members. private String className; /** - * Creates a new UsagePrinter that prints to System.out. + * Creates a new UsagePrinter that prints to the given writer. * @param usageMarker the usage marker that was used to mark the * classes and class members. * @param printUnusedItems a flag that indicates whether only unused items * should be printed, or alternatively, only used * items. - */ - public UsagePrinter(UsageMarker usageMarker, - boolean printUnusedItems) - { - this(usageMarker, printUnusedItems, System.out); - } - - - /** - * Creates a new UsagePrinter that prints to the given stream. - * @param usageMarker the usage marker that was used to mark the - * classes and class members. - * @param printUnusedItems a flag that indicates whether only unused items - * should be printed, or alternatively, only used - * items. - * @param printStream the stream to which to print. + * @param printWriter the writer to which to print. */ public UsagePrinter(UsageMarker usageMarker, boolean printUnusedItems, - PrintStream printStream) + PrintWriter printWriter) { this.usageMarker = usageMarker; this.printUnusedItems = printUnusedItems; - this.ps = printStream; + this.pw = printWriter; } @@ -102,14 +87,14 @@ } else { - ps.println(ClassUtil.externalClassName(programClass.getName())); + pw.println(ClassUtil.externalClassName(programClass.getName())); } } else { if (printUnusedItems) { - ps.println(ClassUtil.externalClassName(programClass.getName())); + pw.println(ClassUtil.externalClassName(programClass.getName())); } } } @@ -123,7 +108,7 @@ { printClassNameHeader(); - ps.println(" " + + pw.println(" " + ClassUtil.externalFullFieldDescription( programField.getAccessFlags(), programField.getName(programClass), @@ -138,9 +123,9 @@ { printClassNameHeader(); - ps.print(" "); + pw.print(" "); programMethod.attributesAccept(programClass, this); - ps.println(ClassUtil.externalFullMethodDescription( + pw.println(ClassUtil.externalFullMethodDescription( programClass.getName(), programMethod.getAccessFlags(), programMethod.getName(programClass), @@ -162,7 +147,7 @@ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) { - ps.print(lineNumberTableAttribute.getLowestLineNumber() + ":" + + pw.print(lineNumberTableAttribute.getLowestLineNumber() + ":" + lineNumberTableAttribute.getHighestLineNumber() + ":"); } @@ -177,7 +162,7 @@ { if (className != null) { - ps.println(ClassUtil.externalClassName(className) + ":"); + pw.println(ClassUtil.externalClassName(className) + ":"); className = null; } } diff -Nru proguard-6.0.3/core/src/proguard/shrink/UsedClassFilter.java proguard-6.2.0/core/src/proguard/shrink/UsedClassFilter.java --- proguard-6.0.3/core/src/proguard/shrink/UsedClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/UsedClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/shrink/UsedMemberFilter.java proguard-6.2.0/core/src/proguard/shrink/UsedMemberFilter.java --- proguard-6.0.3/core/src/proguard/shrink/UsedMemberFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/shrink/UsedMemberFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/SubclassedClassFilter.java proguard-6.2.0/core/src/proguard/SubclassedClassFilter.java --- proguard-6.0.3/core/src/proguard/SubclassedClassFilter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/SubclassedClassFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/Targeter.java proguard-6.2.0/core/src/proguard/Targeter.java --- proguard-6.0.3/core/src/proguard/Targeter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/Targeter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/UpToDateChecker.java proguard-6.2.0/core/src/proguard/UpToDateChecker.java --- proguard-6.0.3/core/src/proguard/UpToDateChecker.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/UpToDateChecker.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/AndMatcher.java proguard-6.2.0/core/src/proguard/util/AndMatcher.java --- proguard-6.0.3/core/src/proguard/util/AndMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/AndMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ArrayUtil.java proguard-6.2.0/core/src/proguard/util/ArrayUtil.java --- proguard-6.0.3/core/src/proguard/util/ArrayUtil.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ArrayUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -493,9 +493,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(boolean[] array1, int size1, boolean[] array2, int size2) @@ -504,19 +504,14 @@ for (int index = 0; index < minSize; index++) { - if (!array1[index] && array2[index]) - { - return -1; - } - else if (array1[index] && !array2[index]) + int comparison = Boolean.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -527,9 +522,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(byte[] array1, int size1, byte[] array2, int size2) @@ -538,19 +533,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Byte.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -572,19 +562,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Character.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -595,9 +580,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(short[] array1, int size1, short[] array2, int size2) @@ -606,19 +591,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Short.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -629,9 +609,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(int[] array1, int size1, int[] array2, int size2) @@ -640,19 +620,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Integer.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -663,9 +638,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(long[] array1, int size1, long[] array2, int size2) @@ -674,19 +649,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Long.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -697,9 +667,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(float[] array1, int size1, float[] array2, int size2) @@ -708,19 +678,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Float.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -731,9 +696,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(double[] array1, int size1, double[] array2, int size2) @@ -742,19 +707,14 @@ for (int index = 0; index < minSize; index++) { - if (array1[index] < array2[index]) - { - return -1; - } - else if (array1[index] > array2[index]) + int comparison = Double.compare(array1[index], array2[index]); + if (comparison != 0) { - return 1; + return comparison; } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } @@ -765,9 +725,9 @@ * @param array2 the second array. * @param size2 the size of the second array. * @return 0 if all elements are the same, - * -1 if the first different element in the first array is smaller - * than the corresponding element in the second array, - * or 1 if it is larger. + * -1 if the first different element in the first array is smaller + * than the corresponding element in the second array, + * or 1 if it is larger. */ public static int compare(Comparable[] array1, int size1, Comparable[] array2, int size2) @@ -783,9 +743,7 @@ } } - return size1 < size2 ? -1 : - size1 == size2 ? 0 : - 1; + return Integer.compare(size1, size2); } diff -Nru proguard-6.0.3/core/src/proguard/util/ClassNameParser.java proguard-6.2.0/core/src/proguard/util/ClassNameParser.java --- proguard-6.0.3/core/src/proguard/util/ClassNameParser.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ClassNameParser.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -309,13 +309,12 @@ int closingBracketIndex = string.indexOf('>', index); if (closingBracketIndex < 0) { - throw new IllegalArgumentException("Missing closing angular bracket"); + throw new IllegalArgumentException("Missing closing angular bracket after opening bracket at index "+index+" in ["+string+"]"); } if (variableStringMatchers == null) { - System.err.println(string); - throw new IllegalArgumentException("References to wildcards are not supported in this argument"); + throw new IllegalArgumentException("References to wildcards are not supported in this argument ["+string+"]"); } String argumentBetweenBrackets = string.substring(index+1, closingBracketIndex); @@ -326,14 +325,14 @@ if (wildcardIndex < 1 || wildcardIndex > variableStringMatchers.size()) { - throw new IllegalArgumentException("Invalid reference to wildcard ("+wildcardIndex+", must lie between 1 and "+variableStringMatchers.size()+")"); + throw new IllegalArgumentException("Invalid reference to wildcard ("+wildcardIndex+", must lie between 1 and "+variableStringMatchers.size()+" in ["+string+"])"); } return wildcardIndex; } catch (NumberFormatException e) { - throw new IllegalArgumentException("Reference to wildcard must be a number ("+argumentBetweenBrackets+")"); + throw new IllegalArgumentException("Reference to wildcard must be a number ["+argumentBetweenBrackets+"] in ["+string+"]"); } } diff -Nru proguard-6.0.3/core/src/proguard/util/CollectionMatcher.java proguard-6.2.0/core/src/proguard/util/CollectionMatcher.java --- proguard-6.0.3/core/src/proguard/util/CollectionMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/CollectionMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ConstantMatcher.java proguard-6.2.0/core/src/proguard/util/ConstantMatcher.java --- proguard-6.0.3/core/src/proguard/util/ConstantMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ConstantMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/Counter.java proguard-6.2.0/core/src/proguard/util/Counter.java --- proguard-6.0.3/core/src/proguard/util/Counter.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/Counter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/EmptyStringMatcher.java proguard-6.2.0/core/src/proguard/util/EmptyStringMatcher.java --- proguard-6.0.3/core/src/proguard/util/EmptyStringMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/EmptyStringMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ExtensionMatcher.java proguard-6.2.0/core/src/proguard/util/ExtensionMatcher.java --- proguard-6.0.3/core/src/proguard/util/ExtensionMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ExtensionMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/FileNameParser.java proguard-6.2.0/core/src/proguard/util/FileNameParser.java --- proguard-6.0.3/core/src/proguard/util/FileNameParser.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/FileNameParser.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/FixedStringMatcher.java proguard-6.2.0/core/src/proguard/util/FixedStringMatcher.java --- proguard-6.0.3/core/src/proguard/util/FixedStringMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/FixedStringMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ListMatcher.java proguard-6.2.0/core/src/proguard/util/ListMatcher.java --- proguard-6.0.3/core/src/proguard/util/ListMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ListMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ListParser.java proguard-6.2.0/core/src/proguard/util/ListParser.java --- proguard-6.0.3/core/src/proguard/util/ListParser.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ListParser.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ListUtil.java proguard-6.2.0/core/src/proguard/util/ListUtil.java --- proguard-6.0.3/core/src/proguard/util/ListUtil.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ListUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/MatchedStringMatcher.java proguard-6.2.0/core/src/proguard/util/MatchedStringMatcher.java --- proguard-6.0.3/core/src/proguard/util/MatchedStringMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/MatchedStringMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/MultiValueMap.java proguard-6.2.0/core/src/proguard/util/MultiValueMap.java --- proguard-6.0.3/core/src/proguard/util/MultiValueMap.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/MultiValueMap.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/NameParser.java proguard-6.2.0/core/src/proguard/util/NameParser.java --- proguard-6.0.3/core/src/proguard/util/NameParser.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/NameParser.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/NotMatcher.java proguard-6.2.0/core/src/proguard/util/NotMatcher.java --- proguard-6.0.3/core/src/proguard/util/NotMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/NotMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/ObjectUtil.java proguard-6.2.0/core/src/proguard/util/ObjectUtil.java --- proguard-6.0.3/core/src/proguard/util/ObjectUtil.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/ObjectUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/OrMatcher.java proguard-6.2.0/core/src/proguard/util/OrMatcher.java --- proguard-6.0.3/core/src/proguard/util/OrMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/OrMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/PrintWriterUtil.java proguard-6.2.0/core/src/proguard/util/PrintWriterUtil.java --- proguard-6.0.3/core/src/proguard/util/PrintWriterUtil.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/PrintWriterUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/SettableMatcher.java proguard-6.2.0/core/src/proguard/util/SettableMatcher.java --- proguard-6.0.3/core/src/proguard/util/SettableMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/SettableMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/StringMatcher.java proguard-6.2.0/core/src/proguard/util/StringMatcher.java --- proguard-6.0.3/core/src/proguard/util/StringMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/StringMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/StringParser.java proguard-6.2.0/core/src/proguard/util/StringParser.java --- proguard-6.0.3/core/src/proguard/util/StringParser.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/StringParser.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/StringTransformer.java proguard-6.2.0/core/src/proguard/util/StringTransformer.java --- proguard-6.0.3/core/src/proguard/util/StringTransformer.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/StringTransformer.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/util/StringUtil.java proguard-6.2.0/core/src/proguard/util/StringUtil.java --- proguard-6.0.3/core/src/proguard/util/StringUtil.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/StringUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -163,6 +163,28 @@ } + /** + * Joins the given strings using the provided separator. + * + * @param separator The separator to use. + * @param strings The strings to join. + * @return The input strings, concatenated together using the separator + */ + public static String join(String separator, String... strings) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < strings.length; i++) + { + sb.append(strings[i]); + if (i + 1 < strings.length) + { + sb.append(separator); + } + } + return sb.toString(); + } + + /** * Returns the hexadecimal representation of the given byte array. */ diff -Nru proguard-6.0.3/core/src/proguard/util/VariableStringMatcher.java proguard-6.2.0/core/src/proguard/util/VariableStringMatcher.java --- proguard-6.0.3/core/src/proguard/util/VariableStringMatcher.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/util/VariableStringMatcher.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/core/src/proguard/WordReader.java proguard-6.2.0/core/src/proguard/WordReader.java --- proguard-6.0.3/core/src/proguard/WordReader.java 2018-01-14 23:15:19.000000000 +0000 +++ proguard-6.2.0/core/src/proguard/WordReader.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/debian/changelog proguard-6.2.0/debian/changelog --- proguard-6.0.3/debian/changelog 2019-07-07 19:54:52.000000000 +0000 +++ proguard-6.2.0/debian/changelog 2019-10-30 04:42:50.000000000 +0000 @@ -1,3 +1,17 @@ +proguard (6.2.0-1) unstable; urgency=medium + + * Team upload + * New upstream version 6.2.0 (Closes: #943662) + * Refresh patches for new upstream version + * Add patch to disable download of GSON jar + * Add libgoogle-gson-java and libslf4j-java to build dependencies. + * Remove java8-compatibility patch + * Use debhelper 12 + * Bump Standards-Version to 4.4.1 + * Freshen years in debian/copyright + + -- tony mancill Tue, 29 Oct 2019 21:42:50 -0700 + proguard (6.0.3-2) unstable; urgency=medium * Team upload. diff -Nru proguard-6.0.3/debian/compat proguard-6.2.0/debian/compat --- proguard-6.0.3/debian/compat 2018-12-10 23:15:48.000000000 +0000 +++ proguard-6.2.0/debian/compat 2019-10-30 04:42:50.000000000 +0000 @@ -1 +1 @@ -11 +12 diff -Nru proguard-6.0.3/debian/control proguard-6.2.0/debian/control --- proguard-6.0.3/debian/control 2019-07-07 19:54:37.000000000 +0000 +++ proguard-6.2.0/debian/control 2019-10-30 04:42:50.000000000 +0000 @@ -7,11 +7,13 @@ Komal Sukhani Build-Depends: ant, - debhelper (>= 11), + debhelper (>= 12), default-jdk, gradle, + libgoogle-gson-java, + libslf4j-java, maven-repo-helper -Standards-Version: 4.2.1 +Standards-Version: 4.4.1 Vcs-Git: https://salsa.debian.org/java-team/proguard.git Vcs-Browser: https://salsa.debian.org/java-team/proguard Homepage: http://proguard.sourceforge.net diff -Nru proguard-6.0.3/debian/copyright proguard-6.2.0/debian/copyright --- proguard-6.0.3/debian/copyright 2018-12-10 23:15:48.000000000 +0000 +++ proguard-6.2.0/debian/copyright 2019-10-30 04:42:50.000000000 +0000 @@ -3,7 +3,7 @@ Source: http://proguard.sourceforge.net/ Files: * -Copyright: 2002-2017, Eric Lafortune +Copyright: 2002-2019, Eric Lafortune License: GPL-2+ Files: debian/* @@ -14,6 +14,7 @@ 2015, Kai-Chung Yan 2015, komal Sukhani 2016, Markus Koschany + 2019, tony mancill License: GPL-2+ License: GPL-2+ diff -Nru proguard-6.0.3/debian/patches/01-fix-usage.patch proguard-6.2.0/debian/patches/01-fix-usage.patch --- proguard-6.0.3/debian/patches/01-fix-usage.patch 2018-12-10 23:15:48.000000000 +0000 +++ proguard-6.2.0/debian/patches/01-fix-usage.patch 2019-10-30 04:42:50.000000000 +0000 @@ -3,7 +3,7 @@ Forwarded: not-needed --- a/core/src/proguard/ProGuard.java +++ b/core/src/proguard/ProGuard.java -@@ -547,7 +547,7 @@ +@@ -566,7 +566,7 @@ if (args.length == 0) { System.out.println(VERSION); diff -Nru proguard-6.0.3/debian/patches/02-build-classpath.patch proguard-6.2.0/debian/patches/02-build-classpath.patch --- proguard-6.0.3/debian/patches/02-build-classpath.patch 2018-12-10 23:15:48.000000000 +0000 +++ proguard-6.2.0/debian/patches/02-build-classpath.patch 2019-10-30 04:42:50.000000000 +0000 @@ -3,12 +3,13 @@ Forwarded: not-needed --- a/gradle/build.sh +++ b/gradle/build.sh -@@ -17,7 +17,7 @@ - $(echo $GRADLE_HOME/lib/gradle-base-services-groovy-*.jar):\ +@@ -19,7 +19,8 @@ $(echo $GRADLE_HOME/lib/gradle-core-[0-9]*.jar):\ $(echo $GRADLE_HOME/lib/gradle-core-api-*.jar):\ --$(echo $GRADLE_HOME/lib/groovy-all-*.jar) -+$(echo /usr/share/java/groovy-all-*.jar) + $(echo $GRADLE_HOME/lib/groovy-all-*.jar):\ +-$(echo $GRADLE_HOME/lib/slf4j-api-*.jar) ++$(echo /usr/share/java/groovy-all-*.jar):\ ++$(echo /usr/share/java/slf4j-api.jar) # Make sure the Gradle jars are present. if [ ! -f "${GRADLE_PATH%%:*}" ]; then diff -Nru proguard-6.0.3/debian/patches/04-java8-compatibility.patch proguard-6.2.0/debian/patches/04-java8-compatibility.patch --- proguard-6.0.3/debian/patches/04-java8-compatibility.patch 2019-07-07 19:53:54.000000000 +0000 +++ proguard-6.2.0/debian/patches/04-java8-compatibility.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Description: Preserves the backward compatibility with Java 8 -Author: Emmanuel Bourg -Forwarded: not-needed ---- a/buildscripts/functions.sh -+++ b/buildscripts/functions.sh -@@ -17,7 +17,7 @@ - # Compile java source files. - echo "Compiling $(basename $PWD) ($1)..." - mkdir -p "$OUT" && \ -- javac -nowarn -Xlint:none -sourcepath "$SRC" -d "$OUT" \ -+ javac -nowarn -Xlint:none --release 8 -sourcepath "$SRC" -d "$OUT" \ - "$SRC"/${1//.//}.java 2>&1 \ - | sed -e 's|^| |' || return 1 - diff -Nru proguard-6.0.3/debian/patches/05-disable-gson-download.sh proguard-6.2.0/debian/patches/05-disable-gson-download.sh --- proguard-6.0.3/debian/patches/05-disable-gson-download.sh 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/debian/patches/05-disable-gson-download.sh 2019-10-30 04:42:50.000000000 +0000 @@ -0,0 +1,22 @@ +Description: disable download of GSON jar +Author: tony mancill +Forwarded: not-needed + +--- a/core/build.sh ++++ b/core/build.sh +@@ -8,10 +8,11 @@ + + MAIN_CLASS=proguard.ProGuard + +-GSON_VERSION=2.8.5 +-GSON_URL=https://jcenter.bintray.com/com/google/code/gson/gson/${GSON_VERSION}/gson-${GSON_VERSION}.jar +-GSON_JAR=$LIB/gson-${GSON_VERSION}.jar ++GSON_JAR=/usr/share/java/gson.jar ++#GSON_VERSION=2.8.5 ++#GSON_URL=https://jcenter.bintray.com/com/google/code/gson/gson/${GSON_VERSION}/gson-${GSON_VERSION}.jar ++#GSON_JAR=$LIB/gson-${GSON_VERSION}.jar + +-download "$GSON_URL" "$GSON_JAR" && \ ++#download "$GSON_URL" "$GSON_JAR" && \ + compile $MAIN_CLASS "$GSON_JAR" && \ + createjar "$PROGUARD_JAR" || exit 1 diff -Nru proguard-6.0.3/debian/patches/series proguard-6.2.0/debian/patches/series --- proguard-6.0.3/debian/patches/series 2019-07-07 19:49:06.000000000 +0000 +++ proguard-6.2.0/debian/patches/series 2019-10-30 04:42:50.000000000 +0000 @@ -1,4 +1,4 @@ 01-fix-usage.patch 02-build-classpath.patch 03-disable-wtk-plugin.patch -04-java8-compatibility.patch +05-disable-gson-download.sh diff -Nru proguard-6.0.3/gradle/build.gradle proguard-6.2.0/gradle/build.gradle --- proguard-6.0.3/gradle/build.gradle 2017-08-27 13:29:04.000000000 +0000 +++ proguard-6.2.0/gradle/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -1,21 +1,35 @@ // Gradle build script for the ProGuard Gradle task. apply plugin: 'java' +apply plugin: 'groovy' + +sourceCompatibility = "${target}" +targetCompatibility = "${target}" sourceSets.main { java { srcDirs = ['src'] } + + groovy { + srcDirs = ['src'] + } + resources { srcDirs = ['src'] - include '**/*.properties' include '**/*.gif' include '**/*.png' include '**/*.pro' } } +jar { + metaInf.from 'src/META-INF' +} + dependencies { compile project(':core') + compile('com.android.tools.build:gradle:3.0.0') compile gradleApi() + compile localGroovy() } diff -Nru proguard-6.0.3/gradle/build.sh proguard-6.2.0/gradle/build.sh --- proguard-6.0.3/gradle/build.sh 2017-10-29 20:11:59.000000000 +0000 +++ proguard-6.2.0/gradle/build.sh 2019-09-18 11:52:51.000000000 +0000 @@ -15,9 +15,11 @@ $(echo $GRADLE_HOME/lib/gradle-logging-*.jar):\ $(echo $GRADLE_HOME/lib/gradle-base-services-?.*.jar):\ $(echo $GRADLE_HOME/lib/gradle-base-services-groovy-*.jar):\ +$(echo $GRADLE_HOME/lib/gradle-model-core-*.jar):\ $(echo $GRADLE_HOME/lib/gradle-core-[0-9]*.jar):\ $(echo $GRADLE_HOME/lib/gradle-core-api-*.jar):\ -$(echo $GRADLE_HOME/lib/groovy-all-*.jar) +$(echo $GRADLE_HOME/lib/groovy-all-*.jar):\ +$(echo $GRADLE_HOME/lib/slf4j-api-*.jar) # Make sure the Gradle jars are present. if [ ! -f "${GRADLE_PATH%%:*}" ]; then diff -Nru proguard-6.0.3/gradle/build.xml proguard-6.2.0/gradle/build.xml --- proguard-6.0.3/gradle/build.xml 2017-09-23 12:01:07.000000000 +0000 +++ proguard-6.2.0/gradle/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,6 +3,7 @@ + @@ -11,8 +12,10 @@ + +
@@ -36,6 +39,8 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-gradle @@ -19,7 +19,7 @@ maven-source-plugin - + maven-compiler-plugin @@ -46,6 +46,12 @@ ${project.version} + com.android.tools.build + gradle + 3.0.0 + provided + + org.gradle gradle-logging 3.1 @@ -78,8 +84,12 @@ - gradle - http://repo.gradle.org/gradle/libs-releases-local/ + jcenter + https://jcenter.bintray.com + + + google + https://maven.google.com
diff -Nru proguard-6.0.3/gradle/src/META-INF/gradle-plugins/proguard.properties proguard-6.2.0/gradle/src/META-INF/gradle-plugins/proguard.properties --- proguard-6.0.3/gradle/src/META-INF/gradle-plugins/proguard.properties 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/META-INF/gradle-plugins/proguard.properties 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1 @@ +implementation-class=proguard.gradle.ProGuardPlugin diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/GradleUtil.groovy proguard-6.2.0/gradle/src/proguard/gradle/GradleUtil.groovy --- proguard-6.0.3/gradle/src/proguard/gradle/GradleUtil.groovy 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/GradleUtil.groovy 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,315 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.gradle + +import com.android.build.gradle.api.* +import com.android.build.gradle.internal.tasks.FileSupplier +import com.android.build.gradle.internal.scope.TaskOutputHolder; +import com.android.builder.core.AndroidBuilder +import com.android.builder.model.* +import org.gradle.api.* + +import static com.android.builder.model.AndroidProject.FD_OUTPUTS + + +/** + * Utility functions. + */ +class GradleUtil +{ + static int AGP_VERSION_MAJOR + static int AGP_VERSION_MINOR + + static { + (AGP_VERSION_MAJOR, AGP_VERSION_MINOR) = getAndroidPluginVersion() + } + + + static File getAaptRulesFile(ApkVariant variant, Project project) + { + return project.file("${project.buildDir}/intermediates/proguard/${variant.dirName}/aapt_rules.txt") + } + + + /** + * Constructs the name for a gradle task given the current variant name. The convention of this name is in line + * with the convention of other gradle task names. + */ + static String createVariantTaskName(String variantName) + { + return variantName.split('-') + .inject(new StringBuilder()) { StringBuilder result, String part -> + result.append !part.matches('v[0-9][a-z]') || variantName.startsWith(part) ? + part.capitalize() : + "-${part}" + }.toString() + } + + + /** + * Collects and returns all Proguard files specified by the current variant of the main project and all its flavors. + */ + static Collection getProguardFiles(BaseVariant variant) + { + List fullList = new ArrayList() + + // add the config files from the build type, main config and flavors + fullList.addAll(variant.variantData.variantConfiguration.getDefaultConfig().getProguardFiles()) + fullList.addAll(variant.variantData.variantConfiguration.getBuildType().getProguardFiles()) + + for (ProductFlavor flavor : variant.variantData.variantConfiguration.getProductFlavors()) + { + fullList.addAll(flavor.getProguardFiles()) + } + + return fullList + } + + + /** + * Collects and returns all Proguard files specified by the current variant of the main project and all its flavors + * and all Proguard files specified by the libraries used by the current variant. + */ + static Collection getAllProguardFiles(BaseVariant variant) + { + List fullList = new ArrayList() + + fullList.addAll(getProguardFiles(variant)) + fullList.addAll(getConsumerProguardFiles(variant).values()) + + return fullList + } + + + /** + * Collects and returns the Proguard files used for each library used by the current variant of the main project. + */ + private static Map getConsumerProguardFiles(BaseVariant variant) + { + List libraries + Map consumerFileMap = new HashMap<>() + + try + { + try + { + libraries = variant.variantData.variantConfiguration.getAllLibraries() + } + catch (Exception e) + { + // The API of VariantConfiguration has changed with + // version 2.2.0-alpha1 of the android plugin. + // Access the new method via reflection. + libraries = variant.variantData.variantConfiguration."getFlatPackageAndroidLibraries"() + } + + for (Object libraryDependency : libraries) + { + // Starting from version 2.3.0-beta1, the type representing + // an Android library has changed from AndroidLibrary to + // AndroidDependency. Access the method by reflection to + // handle different plugin versions. + + File proguardRules = libraryDependency.getProguardRules() + MavenCoordinates mavenCoordinates + + try + { + mavenCoordinates = libraryDependency.getResolvedCoordinates() + } + catch (Exception ex) + { + mavenCoordinates = libraryDependency.getCoordinates() + } + + MyMavenCoordinates coords = new MyMavenCoordinates(mavenCoordinates.groupId, + mavenCoordinates.artifactId, + mavenCoordinates.version) + + if (proguardRules.exists()) + { + consumerFileMap.put(coords, proguardRules) + } + } + } + catch (Exception e) + { + // They changed the enumeration from PROGUARD_RULES to CONSUMER_PROGUARD_RULES in AGP 3.2. + def artifactType + try + { + artifactType = com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.PROGUARD_RULES + } + catch (Exception e2) + { + artifactType = com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.CONSUMER_PROGUARD_RULES + } + // This is similar to how Proguard does it, we add some indirection to get the library maven coordinates. + def artifactCollection = variant.variantData.scope.getArtifactCollection(com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH, + com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL, + artifactType) + + for (def artifact : artifactCollection) + { + File proguardRules = artifact.getFile() + String componentId = artifact.getId().getComponentIdentifier().toString() + String[] coordComponents = componentId.split(':') + MyMavenCoordinates coords + if (componentId.startsWith('project ') || coordComponents.length == 1) + { + coords = new MyMavenCoordinates('', + coordComponents.last(), + '') + } + else + { + coords = new MyMavenCoordinates(coordComponents[0], + coordComponents[1], + coordComponents.length > 2 ? coordComponents[2] : '') + } + + if (proguardRules.exists()) + { + consumerFileMap.put(coords, proguardRules) + } + } + } + + return consumerFileMap + } + + + static def getAndroidPluginVersion() + { + String[] versionSegments + // The Version class was moved from the com.android.builder package to the com.android.builder.model package + // in the Android gradle plugin v3.1.0. + try + { + versionSegments = com.android.builder.model.Version.ANDROID_GRADLE_PLUGIN_VERSION.split('\\.') + } + catch (Exception e) + { + try + { + versionSegments = com.android.builder.Version.ANDROID_GRADLE_PLUGIN_VERSION.split('\\.') + } + catch (Exception e2) + { + throw new GradleException("Unsupported Android Gradle plugin version.", e) + } + } + final int versionMajor = Integer.parseInt(versionSegments[0]) + final int versionMinor = Integer.parseInt(versionSegments[1]) + + return [versionMajor, versionMinor] + } + + + /** + * Because of the interface change of the AndroidBuilder class in the + * 1.4.0-beta2 release of the Android Gradle plugin we use this wrapper to get + * to the bootclasspath. + */ + static List getBootClasspathWorkaround(AndroidBuilder androidBuilder) + { + try + { + return androidBuilder.getBootClasspath(true) + } + catch (Exception ex) + { + return androidBuilder.bootClasspath + } + } + + + static File getMappingDir(Project project, BaseVariant apkVariant) + { + return project.file("${project.buildDir}/${FD_OUTPUTS}/mapping/${apkVariant.dirName}") + } + + + static void setMappingFile(Project project, BaseVariant variant, File mappingFile, Task proguardTask) + { + try + { + // This is the new way to add a mapping file to Android. + // Since version X.X of the Android gradle plugin. + variant.variantData.scope.addTaskOutput(TaskOutputHolder.TaskOutputType.APK_MAPPING, + mappingFile, + proguardTask.name) + } + catch (Throwable t) + { + // We catch a Throwable because TaskOutputType doesn't exist before v3.0 of the Android plugin + // and that causes a NoClassDefFoundError, which is an Error, not an Exception. + try + { + // We set the mapping file the v2.3 way. + // Groovy doesn't support anonymous interfaces, so we coerce a map. + variant.variantData.mappingFileProviderTask = [ + getTask: { return proguardTask }, + get : { return mappingFile } + ] as FileSupplier + } + catch (Exception ex) + { + try + { + // Try to set the mapping file. + // The variantData are protected and internal. + variant.variantData.mappingFile = mappingFile + } + catch (Exception) + { + project.getLogger().warn("ProGuard could not set mapping file for variant '${variant.name}'") + + } + } + } + } + + + // Helper classes. + + private static class MyMavenCoordinates + { + private String groupId; + private String artifactId; + private String version; + + MyMavenCoordinates(String groupId, String artifactId, String version) + { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + } + + @Override + String toString() + { + return (groupId != null ? groupId : "") + ":" + + (artifactId != null ? artifactId : "") + ":" + + (version != null ? version : ""); + } + } +} diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-common.pro proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-common.pro --- proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-common.pro 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-common.pro 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,105 @@ +# Common ProGuard configuration for debug versions and release versions +# of Android apps. +# +# Copyright (c) 2018-2019 Guardsquare NV + +-ignorewarnings +-dontwarn sun.** +-dontwarn javax.** +-dontwarn java.awt.** +-dontwarn java.nio.file.** +-dontwarn org.apache.** +-dontwarn build.IgnoreJava8API + +-android + +# From default AGP configuration. No need to perform preverification. +-dontpreverify + +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses + +-keepattributes *Annotation* + +# From default AGP configuration. +# Make sure that such classes are kept as they are +# referenced from the AndroidManifest.xml or other +# resource files. Some rules might be obsoleted by +# aapt generated rules but keep them to be sure. +-dontnote android.support.v4.app.Fragment +-dontnote com.google.vending.licensing.ILicensingService +-dontnote com.android.vending.licensing.ILicensingService + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgent +-keep public class * extends android.preference.Preference +-keep public class * extends android.support.v4.app.Fragment +-keep public class * extends android.app.Fragment +-keep public class com.google.vending.licensing.ILicensingService +-keep public class com.android.vending.licensing.ILicensingService + +# From the default AGP config: keep constructors that are called from +# the system via reflection. +-keep public class * extends android.view.View { + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); + public void set*(...); +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native +-keepclasseswithmembernames class * { + native ; +} + +# keep setters in Views so that animations can still work. +# see http://proguard.sourceforge.net/manual/examples.html#beans +-keepclassmembers public class * extends android.view.View { + void set*(***); + *** get*(); +} + +# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keepclassmembers class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator CREATOR; +} + +# The support library contains references to newer platform versions. +# Don't warn about those in case this app is linking against an older +# platform version. We know about them, and they are safe. +-dontwarn android.support.** + +# Understand the @Keep support annotation. +-dontnote android.support.annotation.Keep +-keep class android.support.annotation.Keep + +-keep @android.support.annotation.Keep class * {*;} + +-keepclasseswithmembers class * { + @android.support.annotation.Keep ; +} + +-keepclasseswithmembers class * { + @android.support.annotation.Keep ; +} + +-keepclasseswithmembers class * { + @android.support.annotation.Keep (...); +} diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-debug.pro proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-debug.pro --- proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-debug.pro 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-debug.pro 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,9 @@ +# ProGuard configuration for debug versions of Android apps. +# +# Copyright (c) 2018-2019 Guardsquare NV + +-dontshrink +-dontoptimize +-dontobfuscate + +-include proguard-android-common.pro diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-release-optimize.pro proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-release-optimize.pro --- proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-release-optimize.pro 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-release-optimize.pro 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,5 @@ +# ProGuard configuration for optimized release versions of Android apps. +# +# Copyright (c) 2018-2019 Guardsquare NV + +-include proguard-android-common.pro diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-release.pro proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-release.pro --- proguard-6.0.3/gradle/src/proguard/gradle/proguard-android-release.pro 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/proguard-android-release.pro 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,7 @@ +# ProGuard configuration for release versions of Android apps. +# +# Copyright (c) 2018-2019 Guardsquare NV + +-dontoptimize + +-include proguard-android-release-optimize.pro diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/ProGuardConvention.groovy proguard-6.2.0/gradle/src/proguard/gradle/ProGuardConvention.groovy --- proguard-6.0.3/gradle/src/proguard/gradle/ProGuardConvention.groovy 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/ProGuardConvention.groovy 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.gradle + +/** + * Convention with an extra method to retrieve the default configuration files. + */ +class ProGuardConvention +{ + /** + * Returns the full path of the specified internal configuration file. + */ + String getTunedProGuardFile(String name) + { + // The proguardFile method throws an exception on URLs, so we + // return a file name that the task can identify as special. + return '/proguard/gradle/' + name + } +} diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/ProGuardExtension.groovy proguard-6.2.0/gradle/src/proguard/gradle/ProGuardExtension.groovy --- proguard-6.0.3/gradle/src/proguard/gradle/ProGuardExtension.groovy 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/ProGuardExtension.groovy 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.gradle + +import org.gradle.api.Project + +/** + * These options are configurable from a developer's build.gradle file. + * + * @author Thomas Neidhart + */ +class ProGuardExtension +{ + private Project project + + boolean incremental = false + boolean transformExternalLibraries = true + boolean transformSubprojects = true + + + ProGuardExtension() {} + + ProGuardExtension(Project project) + { + this.project = project + } + + boolean isIncremental() + { + return incremental + } + + boolean transformExternalLibraries() + { + return transformExternalLibraries; + } + + boolean transformSubprojects() + { + return transformSubprojects + } +} diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/ProGuardPlugin.groovy proguard-6.2.0/gradle/src/proguard/gradle/ProGuardPlugin.groovy --- proguard-6.0.3/gradle/src/proguard/gradle/ProGuardPlugin.groovy 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/ProGuardPlugin.groovy 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.gradle + +import com.android.build.gradle.AppExtension +import com.android.build.gradle.BasePlugin +import com.android.build.gradle.api.* +import com.android.build.gradle.internal.BadPluginException +import org.gradle.api.* + +import static GradleUtil.*; + + +/** + * This Plugin installs a DexGuard transform in an Android application project. + * + * @author Thomas Neidhart + */ +class ProGuardPlugin +implements Plugin +{ + // Implementations for Plugin. + + @Override + void apply(Project project) + { + if (!project.hasProperty('android')) + { + throw new BadPluginException('The ProGuard plugin requires the Android plugin to function properly.\n' + + 'Please specify\n apply plugin: \'com.android.application\'\n apply plugin: \'proguard\'') + } + + // Add the extra method 'getTunedProGuardFile' to the project. + project.convention.plugins.extraProGuardMethods = new ProGuardConvention() + + def extension = project.extensions.create('proguard', ProGuardExtension) + + // A transform has to be registered before the project is evaluated. + // This forces us to implement an identity transform in case it is + // disabled for a given variant. + BasePlugin androidPlugin = + (BasePlugin)project.plugins.findPlugin('com.android.application') + + // Register our transform. + ProGuardTransform transform = new ProGuardTransform(project, extension, androidPlugin) + + def android = project.extensions.getByType(AppExtension) + android.registerTransform(transform) + + project.afterEvaluate + { + // Go over all application variants. + project.android.applicationVariants.each + { + ApkVariant apkVariant -> + + boolean proguardFilesConfigured = !getProguardFiles(apkVariant).isEmpty() + // TODO: minifyEnabled is deprecated but there is not yet an alternative available + // until the DSL has changed, keep using it for now. + boolean minifyEnabled = apkVariant.buildType.minifyEnabled + if (minifyEnabled) + { + project.getLogger().warn("minifyEnabled detected for variant '${apkVariant.name}'.\n" + + "Please disable this option in your build.gradle file.") + } + + if (proguardFilesConfigured && !minifyEnabled) + { + transform.enableVariant(apkVariant) + + // Make sure that aapt generates a ProGuard rules file. + def variantName = createVariantTaskName(apkVariant.name) + def processResources = + project.tasks.getByName("process${variantName}Resources") + + if (processResources != null) + { + processResources.conventionMapping.proguardOutputFile = { + getAaptRulesFile(apkVariant, project) + } + } + else + { + throw new GradleException("Unsupported Android Gradle plugin version.") + } + } + } + } + } +} diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/ProGuardTask.java proguard-6.2.0/gradle/src/proguard/gradle/ProGuardTask.java --- proguard-6.0.3/gradle/src/proguard/gradle/ProGuardTask.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/ProGuardTask.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -56,9 +56,13 @@ // Accumulated configuration. protected final Configuration configuration = new Configuration(); - // Field acting as a parameter for the class member specification methods. + // Fields acting as parameters for the class member specification methods. + private boolean allowValues; private ClassSpecification classSpecification; + private static final String CONFIGURATION_FILE_NAME_PREFIX = "/proguard/gradle/proguard-"; + private String resolvedConfigurationFileNamePrefix = getProject().file(CONFIGURATION_FILE_NAME_PREFIX).toString(); + // Gradle task inputs and outputs, because annotations on the List fields // (private or not) don't seem to work. Private methods don't work either, @@ -174,7 +178,15 @@ throws ParseException, IOException { // Just collect the arguments, so they can be resolved lazily. - this.configurationFiles.add(configurationFiles); + // Flatten collections, so they are easier to analyze later on. + if (configurationFiles instanceof Collection) + { + this.configurationFiles.addAll((Collection)configurationFiles); + } + else + { + this.configurationFiles.add(configurationFiles); + } } public void injars(Object inJarFiles) @@ -561,7 +573,8 @@ { configuration.whyAreYouKeeping = extendClassSpecifications(configuration.whyAreYouKeeping, - createClassSpecification(classSpecificationString)); + createClassSpecification(false, + classSpecificationString)); } public void whyareyoukeeping(Map classSpecificationArgs) @@ -576,7 +589,8 @@ { configuration.whyAreYouKeeping = extendClassSpecifications(configuration.whyAreYouKeeping, - createClassSpecification(classSpecificationArgs, + createClassSpecification(false, + classSpecificationArgs, classMembersClosure)); } @@ -609,7 +623,8 @@ { configuration.assumeNoSideEffects = extendClassSpecifications(configuration.assumeNoSideEffects, - createClassSpecification(classSpecificationString)); + createClassSpecification(true, + classSpecificationString)); } public void assumenosideeffects(Map classSpecificationArgs, @@ -618,7 +633,8 @@ { configuration.assumeNoSideEffects = extendClassSpecifications(configuration.assumeNoSideEffects, - createClassSpecification(classSpecificationArgs, + createClassSpecification(true, + classSpecificationArgs, classMembersClosure)); } @@ -627,7 +643,8 @@ { configuration.assumeNoExternalSideEffects = extendClassSpecifications(configuration.assumeNoExternalSideEffects, - createClassSpecification(classSpecificationString)); + createClassSpecification(true, + classSpecificationString)); } public void assumenoexternalsideeffects(Map classSpecificationArgs, @@ -636,7 +653,8 @@ { configuration.assumeNoExternalSideEffects = extendClassSpecifications(configuration.assumeNoExternalSideEffects, - createClassSpecification(classSpecificationArgs, + createClassSpecification(true, + classSpecificationArgs, classMembersClosure)); } @@ -645,7 +663,8 @@ { configuration.assumeNoEscapingParameters = extendClassSpecifications(configuration.assumeNoEscapingParameters, - createClassSpecification(classSpecificationString)); + createClassSpecification(true, + classSpecificationString)); } public void assumenoescapingparameters(Map classSpecificationArgs, @@ -654,7 +673,8 @@ { configuration.assumeNoEscapingParameters = extendClassSpecifications(configuration.assumeNoEscapingParameters, - createClassSpecification(classSpecificationArgs, + createClassSpecification(true, + classSpecificationArgs, classMembersClosure)); } @@ -663,7 +683,8 @@ { configuration.assumeNoExternalReturnValues = extendClassSpecifications(configuration.assumeNoExternalReturnValues, - createClassSpecification(classSpecificationString)); + createClassSpecification(true, + classSpecificationString)); } public void assumenoexternalreturnvalues(Map classSpecificationArgs, @@ -672,7 +693,28 @@ { configuration.assumeNoExternalReturnValues = extendClassSpecifications(configuration.assumeNoExternalReturnValues, - createClassSpecification(classSpecificationArgs, + createClassSpecification(true, + classSpecificationArgs, + classMembersClosure)); + } + + public void assumevalues(String classSpecificationString) + throws ParseException + { + configuration.assumeValues = + extendClassSpecifications(configuration.assumeValues, + createClassSpecification(true, + classSpecificationString)); + } + + public void assumevalues(Map classSpecificationArgs, + Closure classMembersClosure) + throws ParseException + { + configuration.assumeValues = + extendClassSpecifications(configuration.assumeValues, + createClassSpecification(true, + classSpecificationArgs, classMembersClosure)); } @@ -1107,6 +1149,7 @@ classSpecification.addField(createMemberSpecification(false, false, + allowValues, memberSpecificationArgs)); } @@ -1121,6 +1164,7 @@ classSpecification.addMethod(createMemberSpecification(true, true, + allowValues, memberSpecificationArgs)); } @@ -1135,6 +1179,7 @@ classSpecification.addMethod(createMemberSpecification(true, false, + allowValues, memberSpecificationArgs)); } @@ -1209,23 +1254,69 @@ } // Lazily apply the external configuration files. - ConfigurableFileCollection fileCollection = - getProject().files(configurationFiles); - - Iterator files = fileCollection.iterator(); - while (files.hasNext()) + for (int index = 0; index < configurationFiles.size(); index++) { - ConfigurationParser parser = - new ConfigurationParser(files.next(), - System.getProperties()); + Object fileObject = configurationFiles.get(index); - try - { - parser.parse(configuration); - } - finally + ConfigurableFileCollection fileCollection = + getProject().files(fileObject); + + // Parse the configuration as a collection of files. + Iterator files = fileCollection.iterator(); + + while (files.hasNext()) { - parser.close(); + File file = files.next(); + + // Check if this is the name of an internal configuration file. + if (isInternalConfigurationFile(file)) + { + getLogger().debug("Loading default configuration file " + + file.getAbsolutePath()); + + String internalConfigFileName = + internalConfigurationFileName(file); + + URL configurationURL = + ProGuardTask.class.getResource(internalConfigFileName); + + if (configurationURL == null) + { + throw new FileNotFoundException("'" + file.getAbsolutePath() + "'"); + } + + // Parse the configuration as a URL. + ConfigurationParser parser = + new ConfigurationParser(configurationURL, + System.getProperties()); + + try + { + parser.parse(configuration); + } + finally + { + parser.close(); + } + } + else + { + getLogger().debug("Loading configuration file " + + file.getAbsolutePath()); + + ConfigurationParser parser = + new ConfigurationParser(file, + System.getProperties()); + + try + { + parser.parse(configuration); + } + finally + { + parser.close(); + } + } } } @@ -1239,6 +1330,33 @@ // Small utility methods. + + /** + * Returns whether the given file object is an internal configuration + * file that is packaged in a jar, for instance + * "/proguard/gradle/proguard-android-debug.pro". + */ + private boolean isInternalConfigurationFile(Object fileObject) + { + return fileObject.toString().startsWith(resolvedConfigurationFileNamePrefix); + } + + + /** + * Returns the name of the internal configuration file that is packaged in + * a jar, for instance "/lib/dexguard-debug.pro". + */ + private String internalConfigurationFileName(Object fileObject) + { + // Trim any added file prefix (like "C:"). + // Make sure we have forward slashes. + return fileObject.toString() + .substring(resolvedConfigurationFileNamePrefix.length() - + CONFIGURATION_FILE_NAME_PREFIX.length()) + .replace('\\', '/'); + } + + /** * Extends the given class path with the given filtered input or output * files. @@ -1299,7 +1417,7 @@ createIfClassSpecification(keepArgs); ClassSpecification classSpecification = - createClassSpecification(classSpecificationString); + createClassSpecification(false, classSpecificationString); return createKeepClassSpecification(allowShrinking, @@ -1326,7 +1444,8 @@ createIfClassSpecification(classSpecificationArgs); ClassSpecification classSpecification = - createClassSpecification(classSpecificationArgs, + createClassSpecification(false, + classSpecificationArgs, classMembersClosure); return @@ -1357,7 +1476,7 @@ return null; } - return createClassSpecification(conditionString); + return createClassSpecification(false, conditionString); } @@ -1389,7 +1508,8 @@ * Creates specifications to keep classes and class members, based on the * given ProGuard-style class specification. */ - private ClassSpecification createClassSpecification(String classSpecificationString) + private ClassSpecification createClassSpecification(boolean allowValues, + String classSpecificationString) throws ParseException { try @@ -1399,7 +1519,7 @@ try { - return parser.parseClassSpecificationArguments(); + return parser.parseClassSpecificationArguments(allowValues); } finally { @@ -1417,7 +1537,8 @@ * Creates a specification of classes and class members, based on the * given parameters. */ - private ClassSpecification createClassSpecification(Map classSpecificationArgs, + private ClassSpecification createClassSpecification(boolean allowValues, + Map classSpecificationArgs, Closure classMembersClosure) throws ParseException { @@ -1448,8 +1569,10 @@ { // Temporarily remember the class specification, so we can add // class member specifications. + this.allowValues = allowValues; this.classSpecification = classSpecification; classMembersClosure.call(classSpecification); + this.allowValues = false; this.classSpecification = null; } @@ -1525,6 +1648,7 @@ */ private MemberSpecification createMemberSpecification(boolean isMethod, boolean isConstructor, + boolean allowValues, Map classSpecificationArgs) throws ParseException { @@ -1534,6 +1658,7 @@ String annotation = (String)classSpecificationArgs.get("annotation"); String name = (String)classSpecificationArgs.get("name"); String parameters = (String)classSpecificationArgs.get("parameters"); + String values = (String)classSpecificationArgs.get("value"); // Perform some basic conversions and checks on the attributes. if (annotation != null) @@ -1555,6 +1680,11 @@ type = JavaConstants.TYPE_VOID; } + if (values != null) + { + throw new ParseException("Values attribute not allowed in constructor specification ["+values+"]"); + } + name = ClassConstants.METHOD_NAME_INIT; } else if ((type != null) ^ (parameters != null)) @@ -1570,6 +1700,19 @@ } } + if (values != null) + { + if (!allowValues) + { + throw new ParseException("Values attribute not allowed in this class specification ["+values+"]"); + } + + if (type == null) + { + throw new ParseException("Values attribute must be specified in combination with type attribute in class member specification ["+values+"]"); + } + } + List parameterList = ListUtil.commaSeparatedList(parameters); String descriptor = @@ -1577,11 +1720,20 @@ type != null ? ClassUtil.internalType(type) : null; - return new MemberSpecification(requiredMemberAccessFlags(true, access), - requiredMemberAccessFlags(false, access), - annotation, - name, - descriptor); + return values != null ? + new MemberValueSpecification(requiredMemberAccessFlags(true, access), + requiredMemberAccessFlags(false, access), + annotation, + name, + descriptor, + parseValues(type, + ClassUtil.internalType(type), + values)) : + new MemberSpecification(requiredMemberAccessFlags(true, access), + requiredMemberAccessFlags(false, access), + annotation, + name, + descriptor); } @@ -1655,6 +1807,100 @@ } + /** + * Parses the given string as a value or value range of the given primitive + * type. For example, values "123" or "100..199" of type "int" ("I"). + */ + private Number[] parseValues(String externalType, + String internalType, + String string) + throws ParseException + { + int rangeIndex = string.lastIndexOf(".."); + return rangeIndex >= 0 ? + new Number[] + { + parseValue(externalType, internalType, string.substring(0, rangeIndex)), + parseValue(externalType, internalType, string.substring(rangeIndex + 2)) + } : + new Number[] + { + parseValue(externalType, internalType, string) + }; + } + + + /** + * Parses the given string as a value of the given primitive type. + * For example, value "123" of type "int" ("I"). + * For example, value "true" of type "boolean" ("Z"), returned as 1. + */ + private Number parseValue(String externalType, + String internalType, + String string) + throws ParseException + { + try + { + switch (internalType.charAt(0)) + { + case ClassConstants.TYPE_BOOLEAN: + { + return parseBoolean(string); + } + case ClassConstants.TYPE_BYTE: + case ClassConstants.TYPE_CHAR: + case ClassConstants.TYPE_SHORT: + case ClassConstants.TYPE_INT: + { + return Integer.decode(string); + } + //case ClassConstants.TYPE_LONG: + //{ + // return Long.decode(string); + //} + //case ClassConstants.TYPE_FLOAT: + //{ + // return Float.valueOf(string); + //} + //case ClassConstants.TYPE_DOUBLE: + //{ + // return Double.valueOf(string); + //} + default: + { + throw new ParseException("Can't handle '"+externalType+"' constant ["+string+"]"); + } + } + } + catch (NumberFormatException e) + { + throw new ParseException("Can't parse "+externalType+" constant ["+string+"]"); + } + } + + + /** + * Parses the given boolean string as an integer (0 or 1). + */ + private Integer parseBoolean(String string) + throws ParseException + { + if ("false".equals(string)) + { + return Integer.valueOf(0); + } + else if ("true".equals(string)) + { + return Integer.valueOf(1); + } + else + { + throw new ParseException("Unknown boolean constant ["+string+"]"); + } + } + + /** * Adds the given class specification to the given list, creating a new list * if necessary. diff -Nru proguard-6.0.3/gradle/src/proguard/gradle/ProGuardTransform.groovy proguard-6.2.0/gradle/src/proguard/gradle/ProGuardTransform.groovy --- proguard-6.0.3/gradle/src/proguard/gradle/ProGuardTransform.groovy 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/gradle/src/proguard/gradle/ProGuardTransform.groovy 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,471 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2019 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.gradle + +import com.android.build.api.transform.* +import com.android.build.gradle.api.* +import com.android.build.gradle.BasePlugin +import com.google.common.collect.ImmutableMap +import org.gradle.api.* +import org.gradle.api.file.FileCollection +import org.gradle.api.logging.LogLevel + +import static GradleUtil.*; + +import java.security.MessageDigest + +/** + * Transform input class files and external libraries with ProGuard. + */ +class ProGuardTransform +extends Transform +{ + private final Project project + private final ProGuardExtension transformExtension + private final BasePlugin androidPlugin + private final Set variants = new HashSet<>() + + + ProGuardTransform(Project project, + ProGuardExtension transformExtension, + BasePlugin androidPlugin) + { + this.project = project + this.transformExtension = transformExtension + this.androidPlugin = androidPlugin + } + + + void enableVariant(ApkVariant variant) + { + variants.add(variant) + } + + + @Override + void transform(TransformInvocation transformInvocation) + throws TransformException, InterruptedException, IOException + { + transform(transformInvocation.context, + transformInvocation.inputs, + transformInvocation.referencedInputs, + transformInvocation.outputProvider, + transformInvocation.incremental) + } + + + @Override + void transform(Context context, + Collection inputs, + Collection referencedInputs, + TransformOutputProvider outputProvider, + boolean isIncremental) + throws IOException, TransformException, InterruptedException + { + context.logging.captureStandardOutput(LogLevel.INFO) + + ApkVariant apkVariant = variants.find { variant -> variant.name == context.variantName } + + if (apkVariant == null) + { + // The transform is not enabled for this variant + // Perform an identity transform, i.e. copy all inputs unchanged to the output + identityTransform(inputs, outputProvider, isIncremental) + return + } + + // Create a dummy task in order to execute ProGuard. + // Gradle prevents instantiation of tasks, thus use create. + // DO NOT CALL task.execute() yourself as explained in the gradle guide. + // This task is created here as the mapping file cannot be set in the transform. + def proguardTask = + project.tasks.create("proguardTransform${createVariantTaskName(apkVariant.name)}", + ProGuardTask) + + def transformedInputs = new HashSet<>() + + // Collect the project input that shall be processed. + inputs*.directoryInputs*.each { + DirectoryInput directoryInput -> + + def name = AGP_VERSION_MAJOR < 3 ? + hashMD5(directoryInput.file.absolutePath) : + directoryInput.file.absolutePath + + def outputDir = outputProvider.getContentLocation(name, + outputTypes, + EnumSet.of(QualifiedContent.Scope.PROJECT), + Format.DIRECTORY) + + StringBuilder inputFilter = new StringBuilder() + + if (isIncremental) + { + processChangedFiles(directoryInput, outputDir, { + File file -> + inputFilter.append(directoryInput.file.toPath().relativize(file.toPath()).toString()) + inputFilter.append(',') + }) + + if (inputFilter.length() > 0) + { + inputFilter.deleteCharAt(inputFilter.length() - 1) + } + } + else + { + inputFilter.append('**.class') + } + + transformedInputs.add(directoryInput.file.absolutePath) + proguardTask.injars (filter: inputFilter.toString(), directoryInput.file.absolutePath) + proguardTask.outjars(outputDir.absolutePath) + } + + // Collect external libraries that shall be processed. + // Each library will stored to a separate jar file. + inputs*.jarInputs*.each { + JarInput jarInput -> + + def name = AGP_VERSION_MAJOR < 3 ? + hashMD5(jarInput.file.absolutePath) : + jarInput.file.absolutePath + + def outputJar = + outputProvider.getContentLocation(name, + outputTypes, + EnumSet.of(QualifiedContent.Scope.SUB_PROJECTS, + QualifiedContent.Scope.EXTERNAL_LIBRARIES), + Format.JAR) + + def copy = isIncremental ? + processChangedJarFile(jarInput, outputJar) : + true + + if (copy) + { + transformedInputs.add(jarInput.file.absolutePath) + proguardTask.injars (filter: '**.class', jarInput.file.absolutePath) + proguardTask.outjars(outputJar.absolutePath) + } + } + + // Collect the needed library jars. + getClasspath(apkVariant, transformedInputs, referencedInputs).each { + proguardTask.libraryjars(it.absolutePath) + } + + // Collect the configuration files. + proguardTask.configuration getAllProguardFiles(apkVariant) + proguardTask.configuration getAaptRulesFile(apkVariant, project) + + // Specify the mapping/seeds/usage files. + File mappingDir = getMappingDir(project, apkVariant) + mappingDir.mkdirs() + File mappingFile = new File(mappingDir, 'mapping.txt') + + proguardTask.printseeds new File(mappingDir, 'seeds.txt') + proguardTask.printusage new File(mappingDir, 'usage.txt') + proguardTask.printmapping mappingFile + + setMappingFile(project, apkVariant, mappingFile, proguardTask) + + // Specify the target class version based on the used minSdkVersion + proguardTask.target(getTargetClassVersion(apkVariant)) + + // If we transform plugin is configured not to transform external + // library, we must not shrink the library classes to fully support + // all backport features. This is actually a hack but there seems + // to be no other way to prevent the initial shrinking. + if (!getScopes().contains(QualifiedContent.Scope.EXTERNAL_LIBRARIES)) + { + proguardTask.useuniqueclassmembernames() + } + + // Hardcode for Android (the release already has it, but it is needed for development versions) + proguardTask.android() + + // Execute ProGuard. + proguardTask.proguard() + } + + + private void identityTransform(Collection inputs, + TransformOutputProvider outputProvider, + boolean isIncremental) + { + // Copy all directories. + inputs*.directoryInputs*.each { + DirectoryInput directoryInput -> + + def name = AGP_VERSION_MAJOR < 3 ? + hashMD5(directoryInput.file.absolutePath) : + directoryInput.file.absolutePath + + def outputDir = outputProvider.getContentLocation(name, + outputTypes, + EnumSet.of(QualifiedContent.Scope.PROJECT), + Format.DIRECTORY) + + Closure includeFile = { true } + + if (isIncremental) + { + FileCollection changedFiles = project.files() + + processChangedFiles(directoryInput, outputDir, { + File file -> changedFiles += project.files(file) + }) + + includeFile = { changedFiles.contains(it) } + } + + project.copy { + it.from (directoryInput.file) { + it.include includeFile + } + it.into outputDir + } + } + + // Copy all external libraries. + inputs*.jarInputs*.each { + JarInput jarInput -> + + def name = AGP_VERSION_MAJOR < 3 ? + hashMD5(jarInput.file.absolutePath) : + jarInput.file.absolutePath + + def outputJar = outputProvider.getContentLocation(name, + outputTypes, + EnumSet.of(QualifiedContent.Scope.SUB_PROJECTS, + QualifiedContent.Scope.EXTERNAL_LIBRARIES), + Format.JAR) + + def copy = isIncremental ? + processChangedJarFile(jarInput, outputJar) : + true + + if (copy) + { + project.copy { + it.from jarInput.file + it.into outputJar.parent + it.rename('(.*)', outputJar.absolutePath) + } + } + } + } + + + private void processChangedFiles(DirectoryInput directoryInput, File outputDir, Closure fileChangedClosure) + { + for (Map.Entry entry : directoryInput.changedFiles) + { + File file = entry.key; + Status status = entry.value + + if (status == Status.ADDED || + status == Status.CHANGED) + { + fileChangedClosure file + } + + if (status == Status.CHANGED || + status == Status.REMOVED) + { + File output = toOutput(directoryInput.file, outputDir, file) + output.delete() + deleteRelated(output) + } + } + } + + + private boolean processChangedJarFile(JarInput jarInput, File outputJar) + { + File file = jarInput.file + Status status = jarInput.status + boolean fileNeedsUpdate = false + + if (status == Status.ADDED || + status == Status.CHANGED) + { + fileNeedsUpdate = true + } + + if (status == Status.CHANGED || + status == Status.REMOVED) + { + File output = toOutput(file, outputJar, file) + output.delete() + } + + return fileNeedsUpdate + } + + + private static File toOutput(File inputDir, File outputDir, File file) + { + return outputDir.toPath().resolve(inputDir.toPath().relativize(file.toPath())).toFile() + } + + + private static void deleteRelated(File file) + { + def className = file.name.replaceFirst(/\.class$/, '') + // Delete any generated Lambda or Util classes. + file.parentFile.eachFile { + if (it.name.matches(/$className\$\$/ + /Lambda.*\.class$/) || + it.name.matches(/$className\$\$/ + /Util.*\.class$/)) + { + it.delete() + } + } + } + + + private def hashMD5(String s) + { + MessageDigest.getInstance("MD5").digest(s.bytes).encodeHex().toString() + } + + + private FileCollection getClasspath(BaseVariant variant, + Set transformedInputs, + Collection referencedInputs) + { + FileCollection classpathFiles = variant.javaCompiler.classpath + for (TransformInput input : referencedInputs) + { + classpathFiles += project.files(input.directoryInputs*.file) + } + + getBootClasspathWorkaround(androidPlugin.androidBuilder).each { + classpathFiles += project.files(it) + } + + // Filter out transformed jar files to avoid duplicate jar file error when + // processing with DexGuard. + return classpathFiles.filter { File file -> !transformedInputs.contains(file.absolutePath) } + } + + + private static String getTargetClassVersion(ApkVariant variant) + { + def minSdkVersion + try + { + minSdkVersion = variant.packageApplication.minSdkVersion + } + catch (Exception e) + { + ApkVariantOutput variantOutput = variant.outputs.first() + minSdkVersion = variantOutput.packageApplication.minSdkVersion + } + + if (minSdkVersion < 19) + { + return "1.6" + } + else if (minSdkVersion < 24) + { + return "1.7" + } + else + { + return "1.8" + } + } + + + @Override + String getName() + { + return "ProGuardTransform" + } + + + @Override + Set getInputTypes() + { + return EnumSet.of(QualifiedContent.DefaultContentType.CLASSES) + } + + + @Override + Set getScopes() + { + List scopes = new ArrayList<>() + scopes.add(QualifiedContent.Scope.PROJECT) + + if (transformExtension.transformExternalLibraries()) + { + scopes.add(QualifiedContent.Scope.EXTERNAL_LIBRARIES) + } + + if (transformExtension.transformSubprojects()) + { + scopes.add(QualifiedContent.Scope.SUB_PROJECTS) + } + + return EnumSet.copyOf(scopes); + } + + + @Override + Set getReferencedScopes() + { + List scopes = new ArrayList<>() + + if (!transformExtension.transformExternalLibraries()) + { + scopes.add(QualifiedContent.Scope.EXTERNAL_LIBRARIES) + } + + if (!transformExtension.transformSubprojects()) + { + scopes.add(QualifiedContent.Scope.SUB_PROJECTS) + } + + scopes.add(QualifiedContent.Scope.TESTED_CODE) + + return EnumSet.copyOf(scopes); + } + + + @Override + Map getParameterInputs() + { + return ImmutableMap.builder() + .put("incremental", transformExtension.incremental) + .put("transformExternalLibraries", transformExtension.transformExternalLibraries) + .put("transformSubprojects", transformExtension.transformSubprojects) + .build() + } + + + @Override + boolean isIncremental() + { + return transformExtension.isIncremental() + } +} diff -Nru proguard-6.0.3/gui/build.gradle proguard-6.2.0/gui/build.gradle --- proguard-6.0.3/gui/build.gradle 2017-09-19 20:47:03.000000000 +0000 +++ proguard-6.2.0/gui/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -2,6 +2,9 @@ apply plugin: 'java' +sourceCompatibility = "${target}" +targetCompatibility = "${target}" + sourceSets.main { java { srcDirs = ['src'] diff -Nru proguard-6.0.3/gui/build.xml proguard-6.2.0/gui/build.xml --- proguard-6.0.3/gui/build.xml 2017-08-27 13:25:29.000000000 +0000 +++ proguard-6.2.0/gui/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,6 +3,8 @@ + + @@ -29,6 +31,8 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-gui diff -Nru proguard-6.0.3/gui/src/proguard/gui/boilerplate.pro proguard-6.2.0/gui/src/proguard/gui/boilerplate.pro --- proguard-6.0.3/gui/src/proguard/gui/boilerplate.pro 2017-10-29 21:31:36.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/boilerplate.pro 2019-09-18 11:52:51.000000000 +0000 @@ -107,7 +107,7 @@ -keep public class * extends android.content.ContentProvider -# More Android - View classes. Keep all Android views and their constructors and setters. +# More Android... - View classes. Keep all Android views and their constructors and setters. -keep public class * extends android.view.View { public (android.content.Context); public (android.content.Context, android.util.AttributeSet); @@ -115,7 +115,7 @@ public void set*(...); } -# More Android - Layout classes. Keep classes with constructors that may be referenced from Android layout +# More Android... - Layout classes. Keep classes with constructors that may be referenced from Android layout # files. -keepclasseswithmembers class * { public (android.content.Context, android.util.AttributeSet); @@ -124,30 +124,30 @@ public (android.content.Context, android.util.AttributeSet, int); } -# More Android - Contexts. Keep all extensions of Android Context. +# More Android... - Contexts. Keep all extensions of Android Context. -keepclassmembers class * extends android.content.Context { public void *(android.view.View); public void *(android.view.MenuItem); } -# More Android - Parcelables. Keep all extensions of Android Parcelables. +# More Android... - Parcelables. Keep all extensions of Android Parcelables. -keepclassmembers class * implements android.os.Parcelable { static ** CREATOR; } -# More Android - R classes. Keep all fields of Android R classes. +# More Android... - R classes. Keep all fields of Android R classes. -keepclassmembers class **.R$* { public static ; } -# Android annotations - Support annotations. Support annotations for Android. +# Android annotations... - Support annotations. Support annotations for Android. -keep @android.support.annotation.Keep class * -keepclassmembers class * { @android.support.annotation.Keep *; } -# Android annotations - Facebook keep annotations. Keep annotations for Facebook. +# Android annotations... - Facebook keep annotations. Keep annotations for Facebook. -keep @com.facebook.proguard.annotations.DoNotStrip class * -keepclassmembers class * { @com.facebook.proguard.annotations.DoNotStrip *; @@ -157,7 +157,7 @@ @com.facebook.proguard.annotations.KeepGettersAndSetters *; } -# Android annotations - ProGuard annotations. Keep annotations for ProGuard. +# Android annotations... - ProGuard annotations. Keep annotations for ProGuard. -keep @proguard.annotation.Keep class * -keepclassmembers class * { @proguard.annotation.Keep *; @@ -207,7 +207,7 @@ } -keepnames @proguard.annotation.KeepName class * -# Android annotations - Google keep annotations. Keep annotations for Google. +# Android annotations... - Google keep annotations. Keep annotations for Google. -keepclassmembernames class * { @com.google.android.gms.common.annotation.KeepName *; } @@ -215,20 +215,20 @@ -# Android libraries - Design support libraries. Keep setters for design support libraries. +# Android libraries... - Design support libraries. Keep setters for design support libraries. -keep !abstract class android.support.design.widget.* implements android.support.design.widget.CoordinatorLayout$Behavior { (android.content.Context, android.util.AttributeSet); } -keepnames class android.support.design.widget.CoordinatorLayout -# Android libraries - Kotlin. Keep some methods for Kotlin for Android Development. +# Android libraries... - Kotlin. Keep some methods for Kotlin for Android Development. -keepclassmembers,allowshrinking,allowobfuscation class kotlin.jvm.internal.Intrinsics { void throwNpe(); } -# Android libraries - Google Play Services. Keep classes for Google Play Services. +# Android libraries... - Google Play Services. Keep classes for Google Play Services. -keep class com.google.android.gms.tagmanager.TagManagerService -keep class com.google.android.gms.measurement.AppMeasurement -keep class com.google.android.gms.measurement.AppMeasurementReceiver @@ -257,7 +257,7 @@ public static final java.lang.String NULL; } -# Android libraries - Firebase. Keep classes for Firebase for Android. +# Android libraries... - Firebase. Keep classes for Firebase for Android. -keep class com.google.firebase.FirebaseApp -keep class com.google.firebase.auth.FirebaseAuth -keep class com.google.firebase.crash.FirebaseCrash @@ -265,16 +265,16 @@ com.google.firebase.database.connection.idl.IPersistentConnectionImpl -keep class com.google.firebase.iid.FirebaseInstanceId -# Android libraries - Google Cloud Messaging. Keep classes for Google Cloud Messaging. +# Android libraries... - Google Cloud Messaging. Keep classes for Google Cloud Messaging. -keep,allowshrinking class **.GCMIntentService -# Android libraries - Guava. Keep classes for the Guava libraries. +# Android libraries... - Guava. Keep classes for the Guava libraries. -keepclassmembers class com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator { sun.misc.Unsafe theUnsafe; } -# Android libraries - RxJava. Keep classes for RxJava. +# Android libraries... - RxJava. Keep classes for RxJava. -keepclassmembers class rx.internal.util.unsafe.*Queue { long producerIndex; long consumerIndex; @@ -283,13 +283,13 @@ rx.internal.util.atomic.LinkedQueueNode consumerNode; } -# Android libraries - ActionBarSherlock. Keep classes for ActionBarSherlock. +# Android libraries... - ActionBarSherlock. Keep classes for ActionBarSherlock. -keepclassmembers !abstract class * extends com.actionbarsherlock.ActionBarSherlock { (android.app.Activity, int); } -# Android libraries - GSON. Keep classes for the GSON library. +# Android libraries... - GSON. Keep classes for the GSON library. -keepclassmembers class * { @com.google.gson.annotations.Expose ; } @@ -304,7 +304,7 @@ } -# Android libraries - Dagger code. Keep the classes that Dagger accesses +# Android libraries... - Dagger code. Keep the classes that Dagger accesses # by reflection. -keep class **$$ModuleAdapter -keep class **$$InjectAdapter @@ -325,7 +325,7 @@ @dagger.** *; } -# Android libraries - Butterknife code. Keep the classes that Butterknife accesses +# Android libraries... - Butterknife code. Keep the classes that Butterknife accesses # by reflection. -keepclasseswithmembers class * { @butterknife.* ; @@ -358,7 +358,7 @@ -keep,allowobfuscation @interface butterknife.* -dontwarn butterknife.internal.ButterKnifeProcessor -# Android libraries - Roboguice. Keep classes for RoboGuice. +# Android libraries... - Roboguice. Keep classes for RoboGuice. -keepclassmembers class * implements com.google.inject.Module { (android.content.Context); (); @@ -375,17 +375,17 @@ -keep,allowobfuscation class roboguice.inject.SharedPreferencesProvider$PreferencesNameHolder -dontnote com.google.inject.Module -# Android libraries - Otto. Keep classes for Otto. +# Android libraries... - Otto. Keep classes for Otto. -keepclassmembers,allowobfuscation class * { @com.squareup.otto.* ; } -# Android libraries - Greenrobot EventBus V2. +# Android libraries... - Greenrobot EventBus V2. -keepclassmembers class * { public void onEvent*(***); } -# Android libraries - Greenrobot EventBus V3. +# Android libraries... - Greenrobot EventBus V3. -keep enum org.greenrobot.eventbus.ThreadMode { *; } -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { @@ -395,7 +395,7 @@ -keepclassmembers,allowobfuscation class ** { @org.greenrobot.eventbus.Subscribe ; } -# Android libraries - Google API. Keep classes and field for Google API. +# Android libraries... - Google API. Keep classes and field for Google API. -keepclassmembers class * { @com.google.api.client.util.Key ; @com.google.api.client.util.Value ; @@ -406,17 +406,17 @@ handleExceptionForNewInstance(java.lang.Exception, java.lang.Class); } -# Android libraries - Facebook API. Keep methods for the Facebook API. +# Android libraries... - Facebook API. Keep methods for the Facebook API. -keepclassmembers interface com.facebook.model.GraphObject { ; } -# Android libraries - Javascript interfaces. Keep all methods from Android Javascripts. +# Android libraries... - Javascript interfaces. Keep all methods from Android Javascripts. -keepclassmembers class * { @android.webkit.JavascriptInterface ; } -# Android libraries - Compatibility classes. Avoid merging and inlining compatibility classes. +# Android libraries... - Compatibility classes. Avoid merging and inlining compatibility classes. -keep,allowshrinking,allowobfuscation class android.support.**Compat*, android.support.**Honeycomb*, @@ -439,7 +439,7 @@ -keep,allowobfuscation,allowshrinking @android.annotation.TargetApi class android.support.** { *; } -# Android libraries - Signatures. Keep setters for signature optimized with class from API level 19 or +# Android libraries... - Signatures. Keep setters for signature optimized with class from API level 19 or # higher. -keep,allowshrinking,allowobfuscation class android.support.v4.app.FragmentState$InstantiationException { @@ -450,18 +450,18 @@ (...); } -# Android libraries - Fields accessed before initialization. Keep fields that are accessed before +# Android libraries... - Fields accessed before initialization. Keep fields that are accessed before # initialization. -keepclassmembers,allowshrinking,allowobfuscation class android.support.**,com.google.android.gms.**.internal.** { !static final ; } -# Android libraries - Sensitive classes. Keep sensitive classes. +# Android libraries... - Sensitive classes. Keep sensitive classes. -keep,allowshrinking,allowobfuscation class com.google.android.gms.**.z* { *; } -# Android libraries - Injection. Keep classes for injection in Guice/RoboGuice/Dagger/ActionBarSherlock. +# Android libraries... - Injection. Keep classes for injection in Guice/RoboGuice/Dagger/ActionBarSherlock. -keep,allowobfuscation class * implements com.google.inject.Provider -keep,allowobfuscation @interface javax.inject.** { *; } -keep,allowobfuscation @interface com.google.inject.** { *; } @@ -478,7 +478,7 @@ @com.google.inject.Inject (...); } -# Android libraries - Retrofit. Keep classes for Retrofit. +# Android libraries... - Retrofit. Keep classes for Retrofit. -keepclassmembers @retrofit.http.RestMethod @interface * { ; } @@ -488,7 +488,7 @@ -keep,allowobfuscation @retrofit.http.RestMethod @interface * -keep,allowobfuscation @interface retrofit2.http.** -# Android libraries - Google inject. Keep classes for Google inject. +# Android libraries... - Google inject. Keep classes for Google inject. -keepclassmembers class * { void finalizeReferent(); } @@ -499,7 +499,7 @@ -keepnames class com.google.inject.internal.util.$FinalizableReference -# Android libraries - Jackson. Keep classes for Jackson. +# Android libraries... - Jackson. Keep classes for Jackson. -keepclassmembers class * { @org.codehaus.jackson.annotate.* ; } @@ -509,7 +509,7 @@ boolean is*(); } -# Android libraries - Crashlytics. Keep classes for Crashlytics. +# Android libraries... - Crashlytics. Keep classes for Crashlytics. -keep class * extends io.fabric.sdk.android.Kit diff -Nru proguard-6.0.3/gui/src/proguard/gui/ClassPathPanel.java proguard-6.2.0/gui/src/proguard/gui/ClassPathPanel.java --- proguard-6.0.3/gui/src/proguard/gui/ClassPathPanel.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ClassPathPanel.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/ClassSpecificationDialog.java proguard-6.2.0/gui/src/proguard/gui/ClassSpecificationDialog.java --- proguard-6.0.3/gui/src/proguard/gui/ClassSpecificationDialog.java 2018-02-17 00:16:58.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ClassSpecificationDialog.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/ClassSpecificationsPanel.java proguard-6.2.0/gui/src/proguard/gui/ClassSpecificationsPanel.java --- proguard-6.0.3/gui/src/proguard/gui/ClassSpecificationsPanel.java 2018-02-16 17:17:43.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ClassSpecificationsPanel.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/ExtensionFileFilter.java proguard-6.2.0/gui/src/proguard/gui/ExtensionFileFilter.java --- proguard-6.0.3/gui/src/proguard/gui/ExtensionFileFilter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ExtensionFileFilter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/FilterBuilder.java proguard-6.2.0/gui/src/proguard/gui/FilterBuilder.java --- proguard-6.0.3/gui/src/proguard/gui/FilterBuilder.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/FilterBuilder.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/FilterDialog.java proguard-6.2.0/gui/src/proguard/gui/FilterDialog.java --- proguard-6.0.3/gui/src/proguard/gui/FilterDialog.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/FilterDialog.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/GUIResources.java proguard-6.2.0/gui/src/proguard/gui/GUIResources.java --- proguard-6.0.3/gui/src/proguard/gui/GUIResources.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/GUIResources.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/GUIResources.properties proguard-6.2.0/gui/src/proguard/gui/GUIResources.properties --- proguard-6.0.3/gui/src/proguard/gui/GUIResources.properties 2018-05-06 20:34:21.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/GUIResources.properties 2019-10-04 12:15:32.000000000 +0000 @@ -1,5 +1,5 @@ # ProGuard -- shrinking, optimization, and obfuscation of Java class files. -# Copyright (c) 2002-2018 Eric Lafortune @ GuardSquare +# Copyright (c) 2002-2019 Guardsquare NV # # Tab names. @@ -16,7 +16,7 @@ # # Splash text. # -developed = Developed by Eric Lafortune +developed = Developed by Guardsquare shrinking = Shrinking optimization = Optimization obfuscation = Obfuscation @@ -25,7 +25,7 @@ # # Panel titles. # -welcome = Welcome to ProGuard, version 6.0.3 +welcome = Welcome to ProGuard, version 6.2.0 options = Options keepAdditional = Keep additional classes and class members keepNamesAdditional = Keep additional class names and class member names @@ -60,17 +60,17 @@

\ With the ReTrace part of this GUI you can de-obfuscate your stack traces.\

\ - ProGuard and ReTrace are written and maintained by Eric Lafortune.\ + ProGuard and ReTrace are written and maintained by Guardsquare.\

\ Official site at Sourceforge: \ http://proguard.sourceforge.net/\
\ - Professional support by GuardSquare: \ + DexGuard and professional support by Guardsquare: \ http://www.guardsquare.com/\

\ Distributed under the GNU General Public License.\
\ - Copyright © 2002-2018. + Copyright © 2002-2019 Guardsquare NV. processingInfo = \ You can now start processing your code, \ @@ -490,10 +490,13 @@ # selectOptimizations = Select optimizations... -field = Field -method = Method -code = Code +library = Library +field = Field +method = Method +code = Code +library_gsonTip = \ + Optimize GSON serialization code. class_marking_finalTip = \ Mark classes as final, whenever possible. class_unboxing_enumTip = \ diff -Nru proguard-6.0.3/gui/src/proguard/gui/KeepSpecificationsPanel.java proguard-6.2.0/gui/src/proguard/gui/KeepSpecificationsPanel.java --- proguard-6.0.3/gui/src/proguard/gui/KeepSpecificationsPanel.java 2018-02-14 00:19:02.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/KeepSpecificationsPanel.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/ListPanel.java proguard-6.2.0/gui/src/proguard/gui/ListPanel.java --- proguard-6.0.3/gui/src/proguard/gui/ListPanel.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ListPanel.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/MemberSpecificationDialog.java proguard-6.2.0/gui/src/proguard/gui/MemberSpecificationDialog.java --- proguard-6.0.3/gui/src/proguard/gui/MemberSpecificationDialog.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/MemberSpecificationDialog.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/MemberSpecificationsPanel.java proguard-6.2.0/gui/src/proguard/gui/MemberSpecificationsPanel.java --- proguard-6.0.3/gui/src/proguard/gui/MemberSpecificationsPanel.java 2018-02-17 00:16:58.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/MemberSpecificationsPanel.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/MessageDialogRunnable.java proguard-6.2.0/gui/src/proguard/gui/MessageDialogRunnable.java --- proguard-6.0.3/gui/src/proguard/gui/MessageDialogRunnable.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/MessageDialogRunnable.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/OptimizationsDialog.java proguard-6.2.0/gui/src/proguard/gui/OptimizationsDialog.java --- proguard-6.0.3/gui/src/proguard/gui/OptimizationsDialog.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/OptimizationsDialog.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/ProGuardGUI.java proguard-6.2.0/gui/src/proguard/gui/ProGuardGUI.java --- proguard-6.0.3/gui/src/proguard/gui/ProGuardGUI.java 2018-03-29 16:37:28.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ProGuardGUI.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 @@ -48,11 +48,12 @@ private static final String BOILERPLATE_CONFIGURATION = "boilerplate.pro"; private static final String DEFAULT_CONFIGURATION = "default.pro"; - private static final String OPTIMIZATIONS_DEFAULT = "*"; - private static final String KEEP_ATTRIBUTE_DEFAULT = "Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod"; - private static final String SOURCE_FILE_ATTRIBUTE_DEFAULT = "SourceFile"; - private static final String ADAPT_RESOURCE_FILE_NAMES_DEFAULT = "**.properties"; - private static final String ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT = "**.properties,META-INF/MANIFEST.MF"; + private static final String OPTIMIZATIONS_DEFAULT = "*"; + private static final String KEEP_ATTRIBUTE_DEFAULT = "Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod"; + private static final String SOURCE_FILE_ATTRIBUTE_DEFAULT = "SourceFile"; + private static final String ADAPT_RESOURCE_FILE_NAMES_DEFAULT = "**.properties"; + private static final String ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT = "**.properties,META-INF/MANIFEST.MF"; + private static final String ELLIPSIS_DOTS = "..."; private static final Border BORDER = BorderFactory.createEtchedBorder(EtchedBorder.RAISED); @@ -163,6 +164,7 @@ private final JTextArea stackTraceTextArea = new JTextArea(3, 40); private final JTextArea reTraceTextArea = new JTextArea(msg("reTraceInfo"), 3, 40); + /** * Creates a new ProGuardGUI. */ @@ -225,6 +227,13 @@ stretchPanelConstraints.anchor = GridBagConstraints.NORTHWEST; stretchPanelConstraints.insets = constraints.insets; + GridBagConstraints containerConstraints = new GridBagConstraints(); + containerConstraints.gridwidth = GridBagConstraints.REMAINDER; + containerConstraints.fill = GridBagConstraints.BOTH; + containerConstraints.weightx = 1.0; + containerConstraints.weighty = 1.0; + containerConstraints.anchor = GridBagConstraints.NORTHWEST; + GridBagConstraints glueConstraints = new GridBagConstraints(); glueConstraints.fill = GridBagConstraints.BOTH; glueConstraints.weightx = 0.01; @@ -334,9 +343,6 @@ loadBoilerplateConfiguration(); // Create the boiler plate keep panels. - JCheckBox previousBox = null; - JTextField previousField = new JTextField(40); - boilerplateKeepCheckBoxes = new JCheckBox[boilerplateKeep.length]; boilerplateKeepTextFields = new JTextField[boilerplateKeep.length]; @@ -352,23 +358,16 @@ shrinkingOptionsPanel.add(tip(printUsageBrowseButton, "selectUsageFile"), constraintsLast); JPanel shrinkingPanel = new JPanel(layout); + shrinkingPanel.add(shrinkingOptionsPanel, panelConstraints); addClassSpecifications(extractClassSpecifications(boilerplateKeep), - shrinkingPanel, boilerplateKeepCheckBoxes, boilerplateKeepTextFields, - previousBox, - previousField); + shrinkingPanel); addBorder(additionalKeepPanel, "keepAdditional"); shrinkingPanel.add(tip(additionalKeepPanel, "keepAdditionalTip"), stretchPanelConstraints); - JScrollPane shrinkingScroll = new JScrollPane(shrinkingPanel); - shrinkingScroll.setBorder(BorderFactory.createEmptyBorder()); - - JPanel totalShrinkingPanel = new JPanel(layout); - totalShrinkingPanel.add(shrinkingScroll, stretchPanelConstraints); - // Create the boiler plate keep names panels. boilerplateKeepNamesCheckBoxes = new JCheckBox[boilerplateKeepNames.length]; boilerplateKeepNamesTextFields = new JTextField[boilerplateKeepNames.length]; @@ -425,23 +424,16 @@ obfuscationOptionsPanel.add(tip(adaptResourceFileContentsTextField, "fileNameFilterTip"), constraintsLastStretch); JPanel obfuscationPanel = new JPanel(layout); + obfuscationPanel.add(obfuscationOptionsPanel, panelConstraints); addClassSpecifications(extractClassSpecifications(boilerplateKeepNames), - obfuscationPanel, boilerplateKeepNamesCheckBoxes, boilerplateKeepNamesTextFields, - previousBox, - previousField); + obfuscationPanel); addBorder(additionalKeepNamesPanel, "keepNamesAdditional"); obfuscationPanel.add(tip(additionalKeepNamesPanel, "keepNamesAdditionalTip"), stretchPanelConstraints); - JScrollPane obfuscationScroll = new JScrollPane(obfuscationPanel); - obfuscationScroll.setBorder(BorderFactory.createEmptyBorder()); - - JPanel totalObfuscationPanel = new JPanel(layout); - totalObfuscationPanel.add(obfuscationScroll, stretchPanelConstraints); - // Create the boiler plate "no side effect methods" panels. boilerplateNoSideEffectMethodCheckBoxes = new JCheckBox[boilerplateNoSideEffectMethods.length]; @@ -461,13 +453,12 @@ optimizationOptionsPanel.add(tip(optimizationPassesSpinner, "optimizationPassesTip"), constraintsLast); JPanel optimizationPanel = new JPanel(layout); + optimizationPanel.add(optimizationOptionsPanel, panelConstraints); addClassSpecifications(boilerplateNoSideEffectMethods, - optimizationPanel, boilerplateNoSideEffectMethodCheckBoxes, null, - previousBox, - previousField); + optimizationPanel); addBorder(additionalNoSideEffectsPanel, "assumeNoSideEffectsAdditional"); optimizationPanel.add(tip(additionalNoSideEffectsPanel, "assumeNoSideEffectsAdditionalTip"), stretchPanelConstraints); @@ -486,7 +477,7 @@ createBrowseButton(printSeedsTextField, msg("selectSeedsFile")); JButton printConfigurationBrowseButton = - createBrowseButton(printConfigurationTextField, msg("selectConfigurationFile")); + createBrowseButton(printConfigurationTextField, msg( "selectConfigurationFile")); JButton dumpBrowseButton = createBrowseButton(dumpTextField, msg("selectDumpFile")); @@ -604,12 +595,27 @@ JButton reTraceButton = new JButton(msg("reTrace")); reTraceButton.addActionListener(new MyReTraceActionListener()); + // Make the shrinking panel so far scrollable. + JPanel scrollableShrinkingPanel = shrinkingPanel; + shrinkingPanel = new JPanel(layout); + shrinkingPanel.add(new JScrollPane(scrollableShrinkingPanel), containerConstraints); + + // Make the obfuscation panel so far scrollable. + JPanel scrollableObfuscationPanel = obfuscationPanel; + obfuscationPanel = new JPanel(layout); + obfuscationPanel.add(new JScrollPane(scrollableObfuscationPanel), containerConstraints); + + // Make the optimization panel so far scrollable. + JPanel scrollableOptimizationPanel = optimizationPanel; + optimizationPanel = new JPanel(layout); + optimizationPanel.add(new JScrollPane(scrollableOptimizationPanel), containerConstraints); + // Create the main tabbed pane. TabbedPane tabs = new TabbedPane(); tabs.add(msg("proGuardTab"), proGuardPanel); tabs.add(msg("inputOutputTab"), inputOutputPanel); - tabs.add(msg("shrinkingTab"), totalShrinkingPanel);//scroll); //shrinkingPanel); - tabs.add(msg("obfuscationTab"), totalObfuscationPanel);//obfuscationPanel); + tabs.add(msg("shrinkingTab"), shrinkingPanel); + tabs.add(msg("obfuscationTab"), obfuscationPanel); tabs.add(msg("optimizationTab"), optimizationPanel); tabs.add(msg("informationTab"), optionsPanel); tabs.add(msg("processTab"), processPanel); @@ -618,39 +624,39 @@ this.getClass().getResource(TITLE_IMAGE_FILE))); // Add the bottom buttons to each panel. - proGuardPanel .add(Box.createGlue(), glueConstraints); - proGuardPanel .add(tip(loadButton, "loadConfigurationTip"), bottomButtonConstraints); - proGuardPanel .add(createNextButton(tabs), lastBottomButtonConstraints); - - inputOutputPanel .add(Box.createGlue(), glueConstraints); - inputOutputPanel .add(createPreviousButton(tabs), bottomButtonConstraints); - inputOutputPanel .add(createNextButton(tabs), lastBottomButtonConstraints); - - totalShrinkingPanel .add(Box.createGlue(), glueConstraints); - totalShrinkingPanel .add(createPreviousButton(tabs), bottomButtonConstraints); - totalShrinkingPanel .add(createNextButton(tabs), lastBottomButtonConstraints); - - totalObfuscationPanel.add(Box.createGlue(), glueConstraints); - totalObfuscationPanel.add(createPreviousButton(tabs), bottomButtonConstraints); - totalObfuscationPanel.add(createNextButton(tabs), lastBottomButtonConstraints); - - optimizationPanel .add(Box.createGlue(), glueConstraints); - optimizationPanel .add(createPreviousButton(tabs), bottomButtonConstraints); - optimizationPanel .add(createNextButton(tabs), lastBottomButtonConstraints); - - optionsPanel .add(Box.createGlue(), glueConstraints); - optionsPanel .add(createPreviousButton(tabs), bottomButtonConstraints); - optionsPanel .add(createNextButton(tabs), lastBottomButtonConstraints); - - processPanel .add(Box.createGlue(), glueConstraints); - processPanel .add(createPreviousButton(tabs), bottomButtonConstraints); - processPanel .add(tip(viewButton, "viewConfigurationTip"), bottomButtonConstraints); - processPanel .add(tip(saveButton, "saveConfigurationTip"), bottomButtonConstraints); - processPanel .add(tip(processButton, "processTip"), lastBottomButtonConstraints); - - reTracePanel .add(Box.createGlue(), glueConstraints); - reTracePanel .add(tip(loadStackTraceButton, "loadStackTraceTip"), bottomButtonConstraints); - reTracePanel .add(tip(reTraceButton, "reTraceTip"), lastBottomButtonConstraints); + proGuardPanel .add(Box.createGlue(), glueConstraints); + proGuardPanel .add(tip(loadButton, "loadConfigurationTip"), bottomButtonConstraints); + proGuardPanel .add(createNextButton(tabs), lastBottomButtonConstraints); + + inputOutputPanel .add(Box.createGlue(), glueConstraints); + inputOutputPanel .add(createPreviousButton(tabs), bottomButtonConstraints); + inputOutputPanel .add(createNextButton(tabs), lastBottomButtonConstraints); + + shrinkingPanel .add(Box.createGlue(), glueConstraints); + shrinkingPanel .add(createPreviousButton(tabs), bottomButtonConstraints); + shrinkingPanel .add(createNextButton(tabs), lastBottomButtonConstraints); + + obfuscationPanel .add(Box.createGlue(), glueConstraints); + obfuscationPanel .add(createPreviousButton(tabs), bottomButtonConstraints); + obfuscationPanel .add(createNextButton(tabs), lastBottomButtonConstraints); + + optimizationPanel.add(Box.createGlue(), glueConstraints); + optimizationPanel.add(createPreviousButton(tabs), bottomButtonConstraints); + optimizationPanel.add(createNextButton(tabs), lastBottomButtonConstraints); + + optionsPanel .add(Box.createGlue(), glueConstraints); + optionsPanel .add(createPreviousButton(tabs), bottomButtonConstraints); + optionsPanel .add(createNextButton(tabs), lastBottomButtonConstraints); + + processPanel .add(Box.createGlue(), glueConstraints); + processPanel .add(createPreviousButton(tabs), bottomButtonConstraints); + processPanel .add(tip(viewButton, "viewConfigurationTip"), bottomButtonConstraints); + processPanel .add(tip(saveButton, "saveConfigurationTip"), bottomButtonConstraints); + processPanel .add(tip(processButton, "processTip"), lastBottomButtonConstraints); + + reTracePanel .add(Box.createGlue(), glueConstraints); + reTracePanel .add(tip(loadStackTraceButton, "loadStackTraceTip"), bottomButtonConstraints); + reTracePanel .add(tip(reTraceButton, "reTraceTip"), lastBottomButtonConstraints); // Add the main tabs to the frame. getContentPane().add(tabs); @@ -662,6 +668,7 @@ loadConfiguration(this.getClass().getResource(DEFAULT_CONFIGURATION)); } + public void startSplash() { splashPanel.start(); @@ -716,6 +723,7 @@ } } + /** * Returns an array containing the ClassSpecifications instances with * matching flags. @@ -726,30 +734,14 @@ { List matches = new ArrayList(); - boolean matched = false; - for (int index = 0; index < keepSpecifications.size(); index++) { KeepClassSpecification keepClassSpecification = (KeepClassSpecification)keepSpecifications.get(index); - - if (keepClassSpecification.comments == null && matched) - { - matches.add(keepClassSpecification); - } - else if (keepClassSpecification.comments != null) - { - - if ((keepClassSpecification.allowShrinking == allowShrinking && - keepClassSpecification.allowObfuscation == allowObfuscation)) - { - matches.add(keepClassSpecification); - matched = true; - } - else - { - matched = false; - } - } + if (keepClassSpecification.allowShrinking == allowShrinking && + keepClassSpecification.allowObfuscation == allowObfuscation) + { + matches.add(keepClassSpecification); + } } KeepClassSpecification[] matchingKeepClassSpecifications = new KeepClassSpecification[matches.size()]; @@ -758,6 +750,7 @@ return matchingKeepClassSpecifications; } + /** * Returns an array containing the ClassSpecification instances of the * given array of KeepClassSpecification instances. @@ -779,11 +772,9 @@ * Creates a panel with the given boiler plate class specifications. */ private void addClassSpecifications(ClassSpecification[] boilerplateClassSpecifications, - JPanel classSpecificationsPanel, JCheckBox[] boilerplateCheckBoxes, JTextField[] boilerplateTextFields, - JCheckBox previousBox, - JTextField previousField) + JPanel classSpecificationsPanel) { // Create some constraints that can be reused. GridBagConstraints constraints = new GridBagConstraints(); @@ -804,167 +795,110 @@ panelConstraints.anchor = GridBagConstraints.NORTHWEST; panelConstraints.insets = constraints.insets; + GridBagConstraints containerConstraints = new GridBagConstraints(); + containerConstraints.gridwidth = GridBagConstraints.REMAINDER; + containerConstraints.fill = GridBagConstraints.BOTH; + containerConstraints.weightx = 1.0; + containerConstraints.weighty = 1.0; + containerConstraints.anchor = GridBagConstraints.NORTHWEST; + GridBagLayout layout = new GridBagLayout(); + JPanel panel = new JPanel(layout); String lastPanelName = null; - JPanel keepSubpanel = null; - boolean commentHasTextField = false; + JPanel subpanel = null; for (int index = 0; index < boilerplateClassSpecifications.length; index++) { - // The panel structure is derived from the comments. - String comments = boilerplateClassSpecifications[index].comments; - String className = boilerplateClassSpecifications[index].className; - - if (comments != null) - { - // Add an empty space if no text field is needed - if (!commentHasTextField && index != 0) - { - JLabel l = new JLabel(""); - keepSubpanel.add(tip(l, "classNamesTip"), constraintsLastStretch); - } - - int dashIndex = comments.indexOf('-'); - int periodIndex = comments.indexOf('.', dashIndex); - commentHasTextField = false; - - final String panelName = comments.substring(0, dashIndex).trim(); - String optionName = comments.substring(dashIndex + 1, periodIndex).replace('_', '.').trim(); - String toolTip = comments.substring(periodIndex + 1); - - if (keepSubpanel == null || !panelName.equals(lastPanelName)) - { - // Create a new foldable keep subpanel and add it. - final JPanel tempKeepSubpanel = new JPanel(layout); - tempKeepSubpanel.setBorder(BorderFactory.createTitledBorder(panelName)); - - final JPanel foldedKeepSubpanel = new JPanel(layout); - foldedKeepSubpanel.setBorder(BorderFactory.createTitledBorder(panelName + "...")); - - foldedKeepSubpanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - foldedKeepSubpanel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent mouseEvent) { - foldedKeepSubpanel.setVisible(false); - tempKeepSubpanel.setVisible(true); - } - }); - - tempKeepSubpanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - tempKeepSubpanel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent mouseEvent) { - foldedKeepSubpanel.setVisible(true); - tempKeepSubpanel.setVisible(false); - } - }); + String comments = boilerplateClassSpecifications[index].comments; - if (!panelName.equals("Keep") && - !panelName.equals("Android") && - !panelName.contains("Remove")) - { - tempKeepSubpanel.setVisible(false); - foldedKeepSubpanel.setVisible(true); - } - else + // Do we have a comment, for a new set of options? + if (comments != null) + { + // Create a new line in the panel. + int dashIndex = comments.indexOf('-'); + int periodIndex = comments.indexOf('.', dashIndex); + String panelName = comments.substring(0, dashIndex).trim(); + String optionName = comments.substring(dashIndex + 1, periodIndex).replace('_', '.').trim(); + String toolTip = comments.substring(periodIndex + 1); + if (!panelName.equals(lastPanelName)) + { + // Create a new subpanel and add it. + subpanel = new JPanel(layout); + if (panelName.endsWith(ELLIPSIS_DOTS)) { - tempKeepSubpanel.setVisible(true); - foldedKeepSubpanel.setVisible(false); + subpanel.setVisible(false); } - keepSubpanel = tempKeepSubpanel; + // Make the contents foldable. + final JPanel foldableSubpanel = new JPanel(layout); + final TitledBorder titledBorder = BorderFactory.createTitledBorder(BORDER, panelName); + foldableSubpanel.setBorder(titledBorder); + foldableSubpanel.add(subpanel, containerConstraints); + + // Fold and unfold the contents when the foldable panel + // is clicked. + final JPanel finalSubpanel = subpanel; + foldableSubpanel.addMouseListener(new MouseAdapter() + { + public void mouseClicked(MouseEvent mouseEvent) + { + // Toggle the visibility and the title. + String title = titledBorder.getTitle(); + if (finalSubpanel.isVisible()) + { + finalSubpanel.setVisible(false); + titledBorder.setTitle(title + ELLIPSIS_DOTS); + } + else + { + finalSubpanel.setVisible(true); + titledBorder.setTitle(title.substring(0, title.length()-3)); + } + } + }); - classSpecificationsPanel.add(foldedKeepSubpanel, panelConstraints); - classSpecificationsPanel.add(keepSubpanel, panelConstraints); + classSpecificationsPanel.add(foldableSubpanel, panelConstraints); - lastPanelName = panelName; - } + lastPanelName = panelName; + } - // Add a check box to each option with comments + // Should we add a text field for the class names? + boolean addTextField = + boilerplateTextFields != null && + (index+1 == boilerplateClassSpecifications.length || + boilerplateClassSpecifications[index+1].comments != null) && + boilerplateClassSpecifications[index].className == null; +; + // Add the check box to the subpanel. JCheckBox boilerplateCheckBox = new JCheckBox(optionName); boilerplateCheckBox.setToolTipText(toolTip); - boilerplateCheckBoxes[index] = boilerplateCheckBox; - previousBox = boilerplateCheckBox; - keepSubpanel.add(boilerplateCheckBox, - boilerplateTextFields != null ? + subpanel.add(boilerplateCheckBox, + addTextField ? constraints : constraintsLastStretch); - // Add a text field if necessary to each option with comments - if (boilerplateTextFields != null) - { - if (className == null || needsTextField(className)) - { - boilerplateTextFields[index] = new JTextField(40); - previousField = boilerplateTextFields[index]; - keepSubpanel.add(tip(boilerplateTextFields[index], "classNamesTip"), constraintsLastStretch); - commentHasTextField = true; - } - else - { - boilerplateTextFields[index] = new JTextField(40); - boilerplateTextFields[index].setText(className); - if (!commentHasTextField && index == boilerplateClassSpecifications.length-1) - { - - JLabel l = new JLabel(""); - - keepSubpanel.add(tip(l, "classNamesTip"), constraintsLastStretch); - } - } - } - - } - - else { - // Match check boxes and text fields with those that belong to the respective comments - boilerplateCheckBoxes[index] = previousBox; + boilerplateCheckBoxes[index] = boilerplateCheckBox; - if (boilerplateTextFields != null) + // Add the text field to the subpanel, if relevant. + if (addTextField) { - if (className == null || needsTextField(className)) - { - if (!commentHasTextField) - { - boilerplateTextFields[index] = new JTextField(40); - previousField = boilerplateTextFields[index]; - keepSubpanel.add(tip(boilerplateTextFields[index], "classNamesTip"), constraintsLastStretch); - commentHasTextField = true; - } - else - { - boilerplateTextFields[index] = previousField; - } - } - else - { - boilerplateTextFields[index] = new JTextField(40); - boilerplateTextFields[index].setText(className); - } + JTextField boilerplateTextField = new JTextField(40); + subpanel.add(tip(boilerplateTextField, "classNamesTip"), constraintsLastStretch); + + boilerplateTextFields[index] = boilerplateTextField; } - } + } + else + { + // Reuse the previous line from the panel, notably the check + // box. + boilerplateCheckBoxes[index] = boilerplateCheckBoxes[index-1]; + } } } - private boolean needsTextField(String string) { - - if (!string.contains("*")) { - return false; - } - - if (string.contains("*") && !string.contains("**")) { - return true; - } - - int indexSingleAsterisk = string.lastIndexOf("*"); - int indexDoubleAsterisk = string.indexOf("**"); - - if (indexDoubleAsterisk+1 != indexSingleAsterisk) { - return true; - } - - return false; - } /** * Adds a standard border with the title that corresponds to the given key @@ -1110,14 +1044,14 @@ // Set up the boilerplate keep options. for (int index = 0; index < boilerplateKeep.length; index++) { - String classNames = findMatchingKeepSpecifications(boilerplateKeep[index], + boilerplateKeepTextFields[index] == null, configuration.keep); boilerplateKeepCheckBoxes[index].setSelected(classNames != null); - - if (boilerplateKeepTextFields != null) { + if (boilerplateKeepTextFields[index] != null) + { boilerplateKeepTextFields[index].setText(classNames == null ? "*" : classNames); } } @@ -1128,10 +1062,12 @@ { String classNames = findMatchingKeepSpecifications(boilerplateKeepNames[index], + boilerplateKeepNamesTextFields[index] == null, configuration.keep); boilerplateKeepNamesCheckBoxes[index].setSelected(classNames != null); - if (boilerplateKeepNamesTextFields != null) { + if (boilerplateKeepNamesTextFields[index] != null) + { boilerplateKeepNamesTextFields[index].setText(classNames == null ? "*" : classNames); } } @@ -1246,22 +1182,6 @@ } } - /** - * Returns the given string in which the asterisks are replaced by the given string 'text'. - */ - private String replaceAsteriskByText(String string, String text) { - - int indexOfSingleAsterisk = string.lastIndexOf("*"); - int indexOfDoubleAsterisk = string.indexOf("**"); - if (indexOfSingleAsterisk != indexOfDoubleAsterisk+1 && indexOfSingleAsterisk != -1) { - string = string.substring(0,indexOfSingleAsterisk) - + text - + string.substring(indexOfSingleAsterisk+1,string.length()); - } - - return string; - } - /** * Returns the ProGuard configuration that reflects the current GUI settings. @@ -1295,31 +1215,9 @@ { if (boilerplateKeepCheckBoxes[index].isSelected()) { - String className = boilerplateKeep[index].className; - String text = boilerplateKeepTextFields[index].getText(); - - if (className != null) - { - boolean containsAsterisk = className.contains("*"); - - if(!containsAsterisk) - { - keep.add(classSpecification(boilerplateKeep[index], className)); - } - else - { - className = replaceAsteriskByText(className,text); - keep.add(classSpecification(boilerplateKeep[index], className)); - } - - } - else - { - keep.add(classSpecification(boilerplateKeep[index],text)); - } -// keep.add(classSpecification(boilerplateKeep[index], -// boilerplateKeepTextFields[index].getText())); - + keep.add(classSpecification(boilerplateKeep[index], + boilerplateKeepTextFields[index] == null ? null : + boilerplateKeepTextFields[index].getText())); } } @@ -1328,17 +1226,9 @@ { if (boilerplateKeepNamesCheckBoxes[index].isSelected()) { - if (boilerplateKeep[index].className != null) - { - keep.add(classSpecification(boilerplateKeepNames[index], boilerplateKeepNames[index].className)); - } - else - { - keep.add(classSpecification(boilerplateKeepNames[index], - boilerplateKeepNamesTextFields[index].getText())); - } -// keep.add(classSpecification(boilerplateKeepNames[index], -// boilerplateKeepNamesTextFields[index].getText())); + keep.add(classSpecification(boilerplateKeepNames[index], + boilerplateKeepNamesTextFields[index] == null ? null : + boilerplateKeepNamesTextFields[index].getText())); } } @@ -1391,9 +1281,9 @@ configuration.obfuscate = obfuscateCheckBox .isSelected(); configuration.printMapping = printMappingCheckBox .isSelected() ? new File(printMappingTextField .getText()) : null; configuration.applyMapping = applyMappingCheckBox .isSelected() ? new File(applyMappingTextField .getText()) : null; - configuration.obfuscationDictionary = obfuscationDictionaryCheckBox .isSelected() ? url(obfuscationDictionaryTextField.getText()) : null; - configuration.classObfuscationDictionary = classObfuscationDictionaryCheckBox .isSelected() ? url(classObfuscationDictionaryTextField.getText()) : null; - configuration.packageObfuscationDictionary = packageObfuscationDictionaryCheckBox .isSelected() ? url(packageObfuscationDictionaryTextField.getText()) : null; + configuration.obfuscationDictionary = obfuscationDictionaryCheckBox .isSelected() ? url(obfuscationDictionaryTextField .getText()) : null; + configuration.classObfuscationDictionary = classObfuscationDictionaryCheckBox .isSelected() ? url(classObfuscationDictionaryTextField .getText()) : null; + configuration.packageObfuscationDictionary = packageObfuscationDictionaryCheckBox .isSelected() ? url(packageObfuscationDictionaryTextField .getText()) : null; configuration.overloadAggressively = overloadAggressivelyCheckBox .isSelected(); configuration.useUniqueClassMemberNames = useUniqueClassMemberNamesCheckBox .isSelected(); configuration.useMixedCaseClassNames = useMixedCaseClassNamesCheckBox .isSelected(); @@ -1486,7 +1376,8 @@ * specifications as a side effect. */ private String findMatchingKeepSpecifications(KeepClassSpecification keepClassSpecificationTemplate, - List keepSpecifications) + boolean matchName, + List keepSpecifications) { if (keepSpecifications == null) { @@ -1499,7 +1390,13 @@ { KeepClassSpecification listedKeepClassSpecification = (KeepClassSpecification)keepSpecifications.get(index); + + // Should we match the original template class name? String className = listedKeepClassSpecification.className; + if (!matchName) + { + keepClassSpecificationTemplate.className = className; + } if (keepClassSpecificationTemplate.equals(listedKeepClassSpecification)) { @@ -1511,11 +1408,6 @@ { buffer.append(','); } - - if (className != null) { - System.out.println("ClassUtil.externalClassName(className) = " + ClassUtil.externalClassName(className)); - } - buffer.append(className == null ? "*" : ClassUtil.externalClassName(className)); // Remove the matching option as a side effect. @@ -1526,6 +1418,7 @@ return buffer == null ? null : buffer.toString(); } + /** * Returns a class specification or keep specification, based on the given * template and the class name to be filled in. @@ -1537,13 +1430,9 @@ ClassSpecification classSpecification = (ClassSpecification)classSpecificationTemplate.clone(); - if (className == null) + // Set the class name in the copy. + if (className != null) { - classSpecification.className = null; - } - else - { - // Set the class name in the copy. classSpecification.className = className.equals("") || className.equals("*") ? @@ -1900,7 +1789,7 @@ { try { - return new URL("file", "", 0, ""); + return new File(path).toURI().toURL(); } catch (MalformedURLException e1) { @@ -2037,6 +1926,7 @@ { gui.startSplash(); } + // Load an initial configuration, if specified. if (argIndex < args.length) { @@ -2052,7 +1942,7 @@ catch (Exception e) { System.out.println("Internal problem starting the ProGuard GUI (" + e.getMessage() + ")"); - e.printStackTrace(); + e.printStackTrace(); } } }); @@ -2060,7 +1950,7 @@ catch (Exception e) { System.out.println("Internal problem starting the ProGuard GUI (" + e.getMessage() + ")"); - e.printStackTrace(); + e.printStackTrace(); } } } diff -Nru proguard-6.0.3/gui/src/proguard/gui/ProGuardRunnable.java proguard-6.2.0/gui/src/proguard/gui/ProGuardRunnable.java --- proguard-6.0.3/gui/src/proguard/gui/ProGuardRunnable.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ProGuardRunnable.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/ReTraceRunnable.java proguard-6.2.0/gui/src/proguard/gui/ReTraceRunnable.java --- proguard-6.0.3/gui/src/proguard/gui/ReTraceRunnable.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/ReTraceRunnable.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/BufferedSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/BufferedSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/BufferedSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/BufferedSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/CircleSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/CircleSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/CircleSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/CircleSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ClipSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/ClipSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ClipSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ClipSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ColorSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/ColorSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ColorSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ColorSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/CompositeSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/CompositeSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/CompositeSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/CompositeSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ConstantColor.java proguard-6.2.0/gui/src/proguard/gui/splash/ConstantColor.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ConstantColor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ConstantColor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ConstantDouble.java proguard-6.2.0/gui/src/proguard/gui/splash/ConstantDouble.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ConstantDouble.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ConstantDouble.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ConstantFont.java proguard-6.2.0/gui/src/proguard/gui/splash/ConstantFont.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ConstantFont.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ConstantFont.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ConstantInt.java proguard-6.2.0/gui/src/proguard/gui/splash/ConstantInt.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ConstantInt.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ConstantInt.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ConstantString.java proguard-6.2.0/gui/src/proguard/gui/splash/ConstantString.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ConstantString.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ConstantString.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ConstantTiming.java proguard-6.2.0/gui/src/proguard/gui/splash/ConstantTiming.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ConstantTiming.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ConstantTiming.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/FontSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/FontSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/FontSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/FontSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ImageSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/ImageSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ImageSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ImageSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/LinearColor.java proguard-6.2.0/gui/src/proguard/gui/splash/LinearColor.java --- proguard-6.0.3/gui/src/proguard/gui/splash/LinearColor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/LinearColor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/LinearDouble.java proguard-6.2.0/gui/src/proguard/gui/splash/LinearDouble.java --- proguard-6.0.3/gui/src/proguard/gui/splash/LinearDouble.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/LinearDouble.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/LinearInt.java proguard-6.2.0/gui/src/proguard/gui/splash/LinearInt.java --- proguard-6.0.3/gui/src/proguard/gui/splash/LinearInt.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/LinearInt.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/LinearTiming.java proguard-6.2.0/gui/src/proguard/gui/splash/LinearTiming.java --- proguard-6.0.3/gui/src/proguard/gui/splash/LinearTiming.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/LinearTiming.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/OverrideGraphics2D.java proguard-6.2.0/gui/src/proguard/gui/splash/OverrideGraphics2D.java --- proguard-6.0.3/gui/src/proguard/gui/splash/OverrideGraphics2D.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/OverrideGraphics2D.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/RectangleSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/RectangleSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/RectangleSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/RectangleSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/SawToothTiming.java proguard-6.2.0/gui/src/proguard/gui/splash/SawToothTiming.java --- proguard-6.0.3/gui/src/proguard/gui/splash/SawToothTiming.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/SawToothTiming.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/ShadowedSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/ShadowedSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/ShadowedSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/ShadowedSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/SineTiming.java proguard-6.2.0/gui/src/proguard/gui/splash/SineTiming.java --- proguard-6.0.3/gui/src/proguard/gui/splash/SineTiming.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/SineTiming.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/SmoothTiming.java proguard-6.2.0/gui/src/proguard/gui/splash/SmoothTiming.java --- proguard-6.0.3/gui/src/proguard/gui/splash/SmoothTiming.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/SmoothTiming.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/SplashPanel.java proguard-6.2.0/gui/src/proguard/gui/splash/SplashPanel.java --- proguard-6.0.3/gui/src/proguard/gui/splash/SplashPanel.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/SplashPanel.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/Sprite.java proguard-6.2.0/gui/src/proguard/gui/splash/Sprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/Sprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/Sprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/TextSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/TextSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/TextSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/TextSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/TimeSwitchSprite.java proguard-6.2.0/gui/src/proguard/gui/splash/TimeSwitchSprite.java --- proguard-6.0.3/gui/src/proguard/gui/splash/TimeSwitchSprite.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/TimeSwitchSprite.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/Timing.java proguard-6.2.0/gui/src/proguard/gui/splash/Timing.java --- proguard-6.0.3/gui/src/proguard/gui/splash/Timing.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/Timing.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/TypeWriterString.java proguard-6.2.0/gui/src/proguard/gui/splash/TypeWriterString.java --- proguard-6.0.3/gui/src/proguard/gui/splash/TypeWriterString.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/TypeWriterString.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/VariableColor.java proguard-6.2.0/gui/src/proguard/gui/splash/VariableColor.java --- proguard-6.0.3/gui/src/proguard/gui/splash/VariableColor.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/VariableColor.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/VariableDouble.java proguard-6.2.0/gui/src/proguard/gui/splash/VariableDouble.java --- proguard-6.0.3/gui/src/proguard/gui/splash/VariableDouble.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/VariableDouble.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/VariableFont.java proguard-6.2.0/gui/src/proguard/gui/splash/VariableFont.java --- proguard-6.0.3/gui/src/proguard/gui/splash/VariableFont.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/VariableFont.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/VariableInt.java proguard-6.2.0/gui/src/proguard/gui/splash/VariableInt.java --- proguard-6.0.3/gui/src/proguard/gui/splash/VariableInt.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/VariableInt.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/VariableSizeFont.java proguard-6.2.0/gui/src/proguard/gui/splash/VariableSizeFont.java --- proguard-6.0.3/gui/src/proguard/gui/splash/VariableSizeFont.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/VariableSizeFont.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/splash/VariableString.java proguard-6.2.0/gui/src/proguard/gui/splash/VariableString.java --- proguard-6.0.3/gui/src/proguard/gui/splash/VariableString.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/splash/VariableString.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/SwingUtil.java proguard-6.2.0/gui/src/proguard/gui/SwingUtil.java --- proguard-6.0.3/gui/src/proguard/gui/SwingUtil.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/SwingUtil.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/TabbedPane.java proguard-6.2.0/gui/src/proguard/gui/TabbedPane.java --- proguard-6.0.3/gui/src/proguard/gui/TabbedPane.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/TabbedPane.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/TextAreaOutputStream.java proguard-6.2.0/gui/src/proguard/gui/TextAreaOutputStream.java --- proguard-6.0.3/gui/src/proguard/gui/TextAreaOutputStream.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/TextAreaOutputStream.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/gui/src/proguard/gui/TextAreaWriter.java proguard-6.2.0/gui/src/proguard/gui/TextAreaWriter.java --- proguard-6.0.3/gui/src/proguard/gui/TextAreaWriter.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/gui/src/proguard/gui/TextAreaWriter.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/LICENSE_exception.md proguard-6.2.0/LICENSE_exception.md --- proguard-6.0.3/LICENSE_exception.md 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/LICENSE_exception.md 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,36 @@ +# Special Exception to the GNU General Public License + +Copyright © 2002-2019 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 + +In addition, as a special exception, Guardsquare NV gives permission to link +the code of this program with the following stand-alone applications: + +- Gradle, +- Apache Ant, +- Apache Maven, +- the Google Android SDK, +- the Intel TXE/DAL SDK, +- the Eclipse ProGuardDT GUI, +- the EclipseME JME IDE, +- the Oracle NetBeans Java IDE, +- the Oracle JME Wireless Toolkit, and +- the Simple Build Tool for Scala (and its scripts). + +and distribute linked combinations including the two. You must obey the GNU +General Public License in all respects for all of the code used other than +these programs. If you modify this file, you may extend this exception to your +version of the file, but you are not obligated to do so. If you do not wish to +do so, delete this exception statement from your version. diff -Nru proguard-6.0.3/LICENSE.md proguard-6.2.0/LICENSE.md --- proguard-6.0.3/LICENSE.md 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/LICENSE.md 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,259 @@ +# GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - +Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +## Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it +to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you distribute +copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. +We wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent must +be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +**0.** This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed under the +terms of this General Public License. The "Program", below, refers to any such +program or work, and a "work based on the Program" means either the Program or +any derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its +contents constitute a work based on the Program (independent of having been +made by running the Program). Whether that is true depends on what the Program +does. + +**1.** You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +**2.** You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such +modifications or work under the terms of Section 1 above, provided that you +also meet all of these conditions: + +- **a)** You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. +- **b)** You must cause any work that you distribute or publish, that in whole + or in part contains or is derived from the Program or any part thereof, to + be licensed as a whole at no charge to all third parties under the terms of + this License. +- **c)** If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be on +the terms of this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +**3.** You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + +- **a)** Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above on + a medium customarily used for software interchange; or, +- **b)** Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, +- **c)** Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only for + noncommercial distribution and only if you received the program in object + code or executable form with such an offer, in accord with Subsection b + above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and +installation of the executable. However, as a special exception, the source +code distributed need not include anything that is normally distributed (in +either source or binary form) with the major components (compiler, kernel, and +so on) of the operating system on which the executable runs, unless that +component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the +source code from the same place counts as distribution of the source code, +even though third parties are not compelled to copy the source along with the +object code. + +**4.** You may not copy, modify, sublicense, or distribute the Program except +as expressly provided under this License. Any attempt otherwise to copy, +modify, sublicense or distribute the Program is void, and will automatically +terminate your rights under this License. However, parties who have received +copies, or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +**5.** You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Program or its derivative works. These actions are prohibited by law if you do +not accept this License. Therefore, by modifying or distributing the Program +(or any work based on the Program), you indicate your acceptance of this +License to do so, and all its terms and conditions for copying, distributing +or modifying the Program or works based on it. + +**6.** Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these terms and +conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +**7.** If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or otherwise) +that contradict the conditions of this License, they do not excuse you from +the conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +**8.** If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +**9.** The Free Software Foundation may publish revised and/or new versions of +the General Public License from time to time. Such new versions will be +similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of this License, +you may choose any version ever published by the Free Software Foundation. + +**10.** If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author to +ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make +exceptions for this. Our decision will be guided by the two goals of +preserving the free status of all derivatives of our free software and of +promoting the sharing and reuse of software generally. + +**NO WARRANTY** + +**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE +THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO +LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR +THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. diff -Nru proguard-6.0.3/README proguard-6.2.0/README --- proguard-6.0.3/README 2018-01-11 21:58:12.000000000 +0000 +++ proguard-6.2.0/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -ProGuard, Java class file shrinker, optimizer, obfuscator, and preverifier -========================================================================== - -This distribution contains the following directories: - -- bin : simple wrapper scripts to run ProGuard, its GUI, and ReTrace -- lib : the main jars, compiled and ready to use with "java -jar ...." -- docs : the complete documentation, licenses, etc. in html format -- examples : some example configuration files - -It also contains the source code and builds scripts: - -- core : the ProGuard core -- retrace : the ReTrace tool -- gui : the ProGuard/ReTrace GUI -- gradle : the ProGuard Gradle plugin -- ant : the ProGuard Ant plugin -- wtk : the ProGuard WTK plugin -- annotations : the optional annotations to configure ProGuard -- buildscripts : various alternative build scripts - - -The best place to start is docs/index.html - - -Example -------- - -If you want to give ProGuard a spin right away, try processing the ProGuard -jar itself: - - cd examples/standalone - ../../bin/proguard.sh @ proguard.pro - -The resulting proguard_out.jar contains the same application, but it's a lot -smaller. - -Enjoy! - -https://www.guardsquare.com/proguard - -Copyright (c) 2002-2018 Eric Lafortune @ GuardSquare diff -Nru proguard-6.0.3/README.md proguard-6.2.0/README.md --- proguard-6.0.3/README.md 1970-01-01 00:00:00.000000000 +0000 +++ proguard-6.2.0/README.md 2019-09-18 11:52:51.000000000 +0000 @@ -0,0 +1,64 @@ +ProGuard, Java bytecode optimizer and obfuscator +================================================ + +This distribution contains the following directories: + +- bin : simple wrapper scripts to run ProGuard, its GUI, and ReTrace +- lib : the main jars, compiled and ready to use with "java -jar ...." +- examples : some example configuration files and projects + +It also contains the source code and build scripts: + +- core : the ProGuard core +- retrace : the ReTrace tool +- gui : the ProGuard/ReTrace GUI +- gradle : the ProGuard Gradle plugin +- ant : the ProGuard Ant plugin +- wtk : the ProGuard WTK plugin +- annotations : the optional annotations to configure ProGuard +- buildscripts : various alternative build scripts + +The best place to start is the [on-line manual](https://www.guardsquare.com/proguard). + + +Example +------- + +If you want to give ProGuard a spin right away, try processing the ProGuard +jar itself: + + cd examples/standalone + ../../bin/proguard.sh @ proguard.pro + +The resulting proguard\_out.jar contains the same application, but it's a lot +smaller. + + +Android example +--------------- + +If you want to see this version of ProGuard integrated in an Android project, +you can look at the small Android HelloWorld project: + + cd examples/android + gradle assembleRelease + + +Downloads +--------- + +You can download ProGuard in various forms: + +- [Pre-built artifacts](https://bintray.com/guardsquare/proguard) at JCenter +- [Pre-built artifacts](https://search.maven.org/search?q=g:net.sf.proguard) at Maven Central +- [Traditional pre-built archives](https://sourceforge.net/projects/proguard/files/) at Sourceforge +- A [Mercurial repository of the source code](https://sourceforge.net/p/proguard/code/) at Sourceforge +- A [Git repository of the source code](https://github.com/Guardsquare/proguard) at Github +- The [complete ProGuard manual](https://www.guardsquare.com/proguard) at Guardsquare + + +Enjoy! + +https://www.guardsquare.com/proguard + +Copyright (c) 2002-2019 Guardsquare NV diff -Nru proguard-6.0.3/retrace/build.gradle proguard-6.2.0/retrace/build.gradle --- proguard-6.0.3/retrace/build.gradle 2017-09-19 20:47:12.000000000 +0000 +++ proguard-6.2.0/retrace/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -2,6 +2,9 @@ apply plugin: 'java' +sourceCompatibility = "${target}" +targetCompatibility = "${target}" + sourceSets.main { java { srcDirs = ['src'] diff -Nru proguard-6.0.3/retrace/build.xml proguard-6.2.0/retrace/build.xml --- proguard-6.0.3/retrace/build.xml 2017-08-27 13:25:37.000000000 +0000 +++ proguard-6.2.0/retrace/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,6 +3,8 @@ + + @@ -23,6 +25,8 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-retrace diff -Nru proguard-6.0.3/retrace/src/proguard/retrace/FrameInfo.java proguard-6.2.0/retrace/src/proguard/retrace/FrameInfo.java --- proguard-6.0.3/retrace/src/proguard/retrace/FrameInfo.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/retrace/src/proguard/retrace/FrameInfo.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/retrace/src/proguard/retrace/FramePattern.java proguard-6.2.0/retrace/src/proguard/retrace/FramePattern.java --- proguard-6.0.3/retrace/src/proguard/retrace/FramePattern.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/retrace/src/proguard/retrace/FramePattern.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/retrace/src/proguard/retrace/FrameRemapper.java proguard-6.2.0/retrace/src/proguard/retrace/FrameRemapper.java --- proguard-6.0.3/retrace/src/proguard/retrace/FrameRemapper.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/retrace/src/proguard/retrace/FrameRemapper.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/retrace/src/proguard/retrace/ReTrace.java proguard-6.2.0/retrace/src/proguard/retrace/ReTrace.java --- proguard-6.0.3/retrace/src/proguard/retrace/ReTrace.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/retrace/src/proguard/retrace/ReTrace.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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 diff -Nru proguard-6.0.3/wtk/build.gradle proguard-6.2.0/wtk/build.gradle --- proguard-6.0.3/wtk/build.gradle 2017-08-27 13:29:04.000000000 +0000 +++ proguard-6.2.0/wtk/build.gradle 2019-09-18 11:52:51.000000000 +0000 @@ -2,6 +2,9 @@ apply plugin: 'java' +sourceCompatibility = "${target}" +targetCompatibility = "${target}" + sourceSets.main { java { srcDirs = ['src'] diff -Nru proguard-6.0.3/wtk/build.xml proguard-6.2.0/wtk/build.xml --- proguard-6.0.3/wtk/build.xml 2017-09-23 12:06:58.000000000 +0000 +++ proguard-6.2.0/wtk/build.xml 2019-09-18 11:52:51.000000000 +0000 @@ -3,6 +3,7 @@ + @@ -34,6 +35,8 @@ net.sf.proguard proguard-parent - 6.0.3 + 6.2.0 ../buildscripts/pom.xml proguard-wtk-plugin diff -Nru proguard-6.0.3/wtk/src/proguard/wtk/ProGuardObfuscator.java proguard-6.2.0/wtk/src/proguard/wtk/ProGuardObfuscator.java --- proguard-6.0.3/wtk/src/proguard/wtk/ProGuardObfuscator.java 2018-01-14 23:15:20.000000000 +0000 +++ proguard-6.2.0/wtk/src/proguard/wtk/ProGuardObfuscator.java 2019-09-18 11:52:51.000000000 +0000 @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2018 GuardSquare NV + * Copyright (c) 2002-2019 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