Skip to content
GitLab
Explore
Sign in
Register
Commits on Source (2)
New upstream version 6.0.2
· dea12d6d
Emmanuel Bourg
authored
Dec 11, 2018
dea12d6d
New upstream version 6.0.3
· 89a9f2bf
Emmanuel Bourg
authored
Dec 11, 2018
89a9f2bf
Hide whitespace changes
Inline
Side-by-side
annotations/pom.xml
View file @
89a9f2bf
...
...
@@ -8,7 +8,7 @@
<parent>
<groupId>
net.sf.proguard
</groupId>
<artifactId>
proguard-parent
</artifactId>
<version>
6.0.
1
</version>
<version>
6.0.
3
</version>
<relativePath>
../buildscripts/pom.xml
</relativePath>
</parent>
<artifactId>
proguard-annotations
</artifactId>
...
...
ant/pom.xml
View file @
89a9f2bf
...
...
@@ -8,7 +8,7 @@
<parent>
<groupId>
net.sf.proguard
</groupId>
<artifactId>
proguard-parent
</artifactId>
<version>
6.0.
1
</version>
<version>
6.0.
3
</version>
<relativePath>
../buildscripts/pom.xml
</relativePath>
</parent>
<artifactId>
proguard-anttask
</artifactId>
...
...
buildscripts/pom.xml
View file @
89a9f2bf
...
...
@@ -7,7 +7,7 @@
<groupId>
net.sf.proguard
</groupId>
<artifactId>
proguard-parent
</artifactId>
<version>
6.0.
1
</version>
<version>
6.0.
3
</version>
<packaging>
pom
</packaging>
<name>
[${project.groupId}] ${project.artifactId}
</name>
<description>
ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier.
</description>
...
...
core/pom.xml
View file @
89a9f2bf
...
...
@@ -8,7 +8,7 @@
<parent>
<groupId>
net.sf.proguard
</groupId>
<artifactId>
proguard-parent
</artifactId>
<version>
6.0.
1
</version>
<version>
6.0.
3
</version>
<relativePath>
../buildscripts/pom.xml
</relativePath>
</parent>
<artifactId>
proguard-base
</artifactId>
...
...
core/src/proguard/ClassSpecificationVisitorFactory.java
View file @
89a9f2bf
...
...
@@ -545,7 +545,7 @@ public class ClassSpecificationVisitorFactory
StringMatcher
nameMatcher
=
name
==
null
?
null
:
new
ListParser
(
new
NameParser
(
variableStringMatchers
)).
parse
(
name
);
StringMatcher
descriptorMatcher
=
name
==
null
?
null
:
StringMatcher
descriptorMatcher
=
descriptor
==
null
?
null
:
new
ListParser
(
new
ClassNameParser
(
variableStringMatchers
)).
parse
(
descriptor
);
StringMatcher
attributesMatcher
=
attributeNames
==
null
?
null
:
...
...
core/src/proguard/DataEntryReaderFactory.java
View file @
89a9f2bf
...
...
@@ -95,31 +95,31 @@ public class DataEntryReaderFactory
}
// Unzip any apks, if necessary.
reader
=
wrapInJarReader
(
reader
,
false
,
isApk
,
apkFilter
,
".apk"
);
reader
=
wrapInJarReader
(
reader
,
false
,
false
,
isApk
,
apkFilter
,
".apk"
);
if
(!
isApk
)
{
// Unzip any jars, if necessary.
reader
=
wrapInJarReader
(
reader
,
false
,
isJar
,
jarFilter
,
".jar"
);
reader
=
wrapInJarReader
(
reader
,
false
,
false
,
isJar
,
jarFilter
,
".jar"
);
if
(!
isJar
)
{
// Unzip any aars, if necessary.
reader
=
wrapInJarReader
(
reader
,
false
,
isAar
,
aarFilter
,
".aar"
);
reader
=
wrapInJarReader
(
reader
,
false
,
false
,
isAar
,
aarFilter
,
".aar"
);
if
(!
isAar
)
{
// Unzip any wars, if necessary.
reader
=
wrapInJarReader
(
reader
,
false
,
isWar
,
warFilter
,
".war"
);
reader
=
wrapInJarReader
(
reader
,
true
,
false
,
isWar
,
warFilter
,
".war"
);
if
(!
isWar
)
{
// Unzip any ears, if necessary.
reader
=
wrapInJarReader
(
reader
,
false
,
isEar
,
earFilter
,
".ear"
);
reader
=
wrapInJarReader
(
reader
,
false
,
false
,
isEar
,
earFilter
,
".ear"
);
if
(!
isEar
)
{
// Unzip any jmods, if necessary.
reader
=
wrapInJarReader
(
reader
,
true
,
isJmod
,
jmodFilter
,
".jmod"
);
reader
=
wrapInJarReader
(
reader
,
true
,
true
,
isJmod
,
jmodFilter
,
".jmod"
);
if
(!
isJmod
)
{
// Unzip any zips, if necessary.
reader
=
wrapInJarReader
(
reader
,
false
,
isZip
,
zipFilter
,
".zip"
);
reader
=
wrapInJarReader
(
reader
,
false
,
false
,
isZip
,
zipFilter
,
".zip"
);
}
}
}
...
...
@@ -132,12 +132,14 @@ public class DataEntryReaderFactory
/**
* Wraps the given DataEntryReader in a JarReader, filtering it if necessary.
* Wraps the given DataEntryReader in a JarReader, filtering it if
* necessary.
* @param reader the data entry reader that can read the
* entries contained in the jar file.
* @param isJmod specifies whether to strip the "classes/"
* prefix from contained .class data entries
* and the jmod magic bytes from the zip.
* @param stripClassesPrefix specifies whether to strip the ""classes/"
* prefix from contained .class data entries.
*@param stripJmodHeader specifies whether to strip the jmod magic
* bytes from the zip.
* @param isJar specifies whether the data entries should
* always be unzipped.
* @param jarFilter otherwise, an optional filter on the data
...
...
@@ -148,21 +150,22 @@ public class DataEntryReaderFactory
* entries.
*/
private
static
DataEntryReader
wrapInJarReader
(
DataEntryReader
reader
,
boolean
isJmod
,
boolean
stripClassesPrefix
,
boolean
stripJmodHeader
,
boolean
isJar
,
List
jarFilter
,
String
jarExtension
)
{
if
(
isJmod
)
if
(
stripClassesPrefix
)
{
reader
=
new
FilteredDataEntryReader
(
new
DataEntryNameFilter
(
new
ExtensionMatcher
(
".c
lass
"
)),
new
PrefixStrippingDataEntryReader
(
"c
lass
es/"
,
reader
),
new
DataEntryNameFilter
(
new
ExtensionMatcher
(
C
lass
Constants
.
CLASS_FILE_EXTENSION
)),
new
PrefixStrippingDataEntryReader
(
C
lass
Constants
.
JMOD_CLASS_FILE_PREFIX
,
reader
),
reader
);
}
// Unzip any jars, if necessary.
DataEntryReader
jarReader
=
new
JarReader
(
reader
,
isJmod
);
DataEntryReader
jarReader
=
new
JarReader
(
reader
,
stripJmodHeader
);
if
(
isJar
)
{
...
...
core/src/proguard/DataEntryWriterFactory.java
View file @
89a9f2bf
...
...
@@ -129,19 +129,30 @@ public class DataEntryWriterFactory
isJmod
||
isZip
);
// If the output is an archive, we'll flatten (unpack the contents of)
// higher level input archives, e.g. when writing into a jar file, we
// flatten zip files.
boolean
flattenApks
=
false
;
boolean
flattenJars
=
flattenApks
||
isApk
;
boolean
flattenAars
=
flattenJars
||
isJar
;
boolean
flattenWars
=
flattenAars
||
isAar
;
boolean
flattenEars
=
flattenWars
||
isWar
;
boolean
flattenJmods
=
flattenEars
||
isEar
;
boolean
flattenZips
=
flattenJmods
||
isJmod
;
// Set up the filtered jar writers.
writer
=
wrapInJarWriter
(
writer
,
f
alse
,
null
,
isZip
,
zipFilter
,
".zip"
,
isApk
||
isJar
||
isAar
||
isWar
||
isEar
||
isJmod
);
writer
=
wrapInJarWriter
(
writer
,
true
,
ClassConstants
.
JMOD_HEADER
,
isJmod
,
jmodFilter
,
".jmod"
,
isApk
||
isJar
||
isAar
||
isWar
||
isEar
);
writer
=
wrapInJarWriter
(
writer
,
f
alse
,
null
,
isEar
,
earFilter
,
".ear"
,
isApk
||
isJar
||
isAar
||
isWar
);
writer
=
wrapInJarWriter
(
writer
,
true
,
null
,
isWar
,
warFilter
,
".war"
,
isApk
||
isJar
||
isAar
);
writer
=
wrapInJarWriter
(
writer
,
f
alse
,
null
,
isAar
,
aarFilter
,
".aar"
,
isApk
||
isJar
);
writer
=
wrapInJarWriter
(
writer
,
f
alse
,
null
,
isJar
,
jarFilter
,
".jar"
,
isApk
);
writer
=
wrapInJarWriter
(
writer
,
f
alse
,
null
,
isApk
,
apkFilter
,
".apk"
,
false
);
writer
=
wrapInJarWriter
(
writer
,
f
lattenZips
,
isZip
,
".zip"
,
zipFilter
,
null
,
null
);
writer
=
wrapInJarWriter
(
writer
,
flattenJmods
,
isJmod
,
".jmod"
,
jmodFilter
,
ClassConstants
.
JMOD_HEADER
,
ClassConstants
.
JMOD_CLASS_FILE_PREFIX
);
writer
=
wrapInJarWriter
(
writer
,
f
lattenEars
,
isEar
,
".ear"
,
earFilter
,
null
,
null
);
writer
=
wrapInJarWriter
(
writer
,
flattenWars
,
isWar
,
".war"
,
warFilter
,
null
,
ClassConstants
.
WAR_CLASS_FILE_PREFIX
);
writer
=
wrapInJarWriter
(
writer
,
f
lattenAars
,
isAar
,
".aar"
,
aarFilter
,
null
,
null
);
writer
=
wrapInJarWriter
(
writer
,
f
lattenJars
,
isJar
,
".jar"
,
jarFilter
,
null
,
null
);
writer
=
wrapInJarWriter
(
writer
,
f
lattenApks
,
isApk
,
".apk"
,
apkFilter
,
null
,
null
);
// Set up for writing out the program classes.
writer
=
new
ClassDataEntryWriter
(
programClassPool
,
writer
);
// Add a filter, if specified.
// Add a
data entry
filter, if specified.
writer
=
filter
!=
null
?
new
FilteredDataEntryWriter
(
new
DataEntryNameFilter
(
...
...
@@ -166,46 +177,61 @@ public class DataEntryWriterFactory
* Wraps the given DataEntryWriter in a JarWriter, filtering if necessary.
*/
private
DataEntryWriter
wrapInJarWriter
(
DataEntryWriter
writer
,
boolean
addClassesPrefix
,
b
yte
[]
heade
r
,
boolean
isJar
,
boolean
flatten
,
b
oolean
isOutputJa
r
,
String
jarFilterExtension
,
List
jarFilter
,
String
jar
Extension
,
boolean
dontWrap
)
byte
[]
jar
Header
,
String
classFilePrefix
)
{
// Zip up jars, if necessary.
DataEntryWriter
jarWriter
=
dontWrap
?
new
ParentDataEntryWriter
(
writer
)
:
new
JarWriter
(
header
,
writer
);
// Add a "classes/" prefix for class files, if specified.
if
(
addClassesPrefix
)
// Flatten jars or zip them up.
DataEntryWriter
jarWriter
;
if
(
flatten
)
{
writer
=
new
FilteredDataEntryWriter
(
new
DataEntryNameFilter
(
new
ExtensionMatcher
(
".class"
)),
new
PrefixAddingDataEntryWriter
(
"classes/"
,
writer
),
writer
);
// Unpack the jar.
jarWriter
=
new
ParentDataEntryWriter
(
writer
);
}
else
{
// Pack the jar.
jarWriter
=
new
JarWriter
(
jarHeader
,
writer
);
// Add a prefix for class files inside the jar, if specified.
if
(
classFilePrefix
!=
null
)
{
jarWriter
=
new
FilteredDataEntryWriter
(
new
DataEntryNameFilter
(
new
ExtensionMatcher
(
ClassConstants
.
CLASS_FILE_EXTENSION
)),
new
PrefixAddingDataEntryWriter
(
classFilePrefix
,
jarWriter
),
jarWriter
);
}
}
//
Add a filter, if specified
.
DataEntryWriter
filteredJarWriter
=
jarFilter
!=
null
?
//
Either zip up the jar or delegate to the original writer
.
return
new
FilteredDataEntryWriter
(
new
DataEntryParentFilter
(
new
DataEntryNameFilter
(
new
ListParser
(
new
FileNameParser
()).
parse
(
jarFilter
))),
jarWriter
)
:
jarWriter
;
// Only zip up jars, unless the output is a jar file itself.
return
new
FilteredDataEntryWriter
(
new
DataEntryParentFilter
(
new
DataEntryNameFilter
(
new
ExtensionMatcher
(
jarExtension
))),
filteredJarWriter
,
isJar
?
jarWriter
:
writer
);
new
ExtensionMatcher
(
jarFilterExtension
))),
// The parent of the data entry is a jar.
// Write the data entry to the jar.
// Apply the jar filter, if specified, to the parent.
jarFilter
!=
null
?
new
FilteredDataEntryWriter
(
new
DataEntryParentFilter
(
new
DataEntryNameFilter
(
new
ListParser
(
new
FileNameParser
()).
parse
(
jarFilter
))),
jarWriter
)
:
jarWriter
,
// The parent of the data entry is not a jar.
// Write the entry to a jar anyway if the output is a jar.
// Otherwise just delegate to the original writer.
isOutputJar
?
jarWriter
:
writer
);
}
}
core/src/proguard/ProGuard.java
View file @
89a9f2bf
...
...
@@ -43,7 +43,7 @@ import java.io.*;
*/
public
class
ProGuard
{
public
static
final
String
VERSION
=
"ProGuard, version 6.0.
1
"
;
public
static
final
String
VERSION
=
"ProGuard, version 6.0.
3
"
;
private
final
Configuration
configuration
;
private
ClassPool
programClassPool
=
new
ClassPool
();
...
...
core/src/proguard/backport/LambdaExpression.java
View file @
89a9f2bf
...
...
@@ -3,6 +3,20 @@
* of Java bytecode.
*
* Copyright (c) 2002-2018 GuardSquare NV
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package
proguard.backport
;
...
...
core/src/proguard/backport/LambdaExpressionCollector.java
View file @
89a9f2bf
...
...
@@ -185,7 +185,8 @@ implements ClassVisitor,
for
(
int
i
=
0
;
i
<
bridgeMethodCount
;
i
++)
{
MethodTypeConstant
methodTypeConstant
=
(
MethodTypeConstant
)
programClass
.
getConstant
(
argumentIndex
++);
getMethodTypeConstant
(
programClass
,
bootstrapMethodInfo
.
u2methodArguments
[
argumentIndex
++]);
lambdaExpression
.
bridgeMethodDescriptors
=
ArrayUtil
.
add
(
lambdaExpression
.
bridgeMethodDescriptors
,
...
...
core/src/proguard/classfile/ClassConstants.java
View file @
89a9f2bf
...
...
@@ -27,9 +27,12 @@ package proguard.classfile;
*/
public
class
ClassConstants
{
public
static
final
byte
[]
JMOD_HEADER
=
new
byte
[]
{
'J'
,
'M'
,
1
,
0
}
;
public
static
final
String
WAR_CLASS_FILE_PREFIX
=
"classes/"
;
public
static
final
String
CLASS_FILE_EXTENSION
=
".class"
;
public
static
final
byte
[]
JMOD_HEADER
=
new
byte
[]
{
'J'
,
'M'
,
1
,
0
};
public
static
final
String
JMOD_CLASS_FILE_PREFIX
=
"classes/"
;
public
static
final
String
CLASS_FILE_EXTENSION
=
".class"
;
public
static
final
int
MAGIC
=
0xCAFEBABE
;
...
...
@@ -51,6 +54,8 @@ public class ClassConstants
public
static
final
int
CLASS_VERSION_1_8_MINOR
=
0
;
public
static
final
int
CLASS_VERSION_1_9_MAJOR
=
53
;
public
static
final
int
CLASS_VERSION_1_9_MINOR
=
0
;
public
static
final
int
CLASS_VERSION_10_MAJOR
=
54
;
public
static
final
int
CLASS_VERSION_10_MINOR
=
0
;
public
static
final
int
CLASS_VERSION_1_0
=
(
CLASS_VERSION_1_0_MAJOR
<<
16
)
|
CLASS_VERSION_1_0_MINOR
;
public
static
final
int
CLASS_VERSION_1_2
=
(
CLASS_VERSION_1_2_MAJOR
<<
16
)
|
CLASS_VERSION_1_2_MINOR
;
...
...
@@ -61,6 +66,7 @@ public class ClassConstants
public
static
final
int
CLASS_VERSION_1_7
=
(
CLASS_VERSION_1_7_MAJOR
<<
16
)
|
CLASS_VERSION_1_7_MINOR
;
public
static
final
int
CLASS_VERSION_1_8
=
(
CLASS_VERSION_1_8_MAJOR
<<
16
)
|
CLASS_VERSION_1_8_MINOR
;
public
static
final
int
CLASS_VERSION_1_9
=
(
CLASS_VERSION_1_9_MAJOR
<<
16
)
|
CLASS_VERSION_1_9_MINOR
;
public
static
final
int
CLASS_VERSION_10
=
(
CLASS_VERSION_10_MAJOR
<<
16
)
|
CLASS_VERSION_10_MINOR
;
public
static
final
int
ACC_PUBLIC
=
0x0001
;
public
static
final
int
ACC_PRIVATE
=
0x0002
;
...
...
core/src/proguard/classfile/JavaConstants.java
View file @
89a9f2bf
...
...
@@ -44,6 +44,7 @@ public interface JavaConstants
public
static
final
String
CLASS_VERSION_1_7_ALIAS
=
"7"
;
public
static
final
String
CLASS_VERSION_1_8_ALIAS
=
"8"
;
public
static
final
String
CLASS_VERSION_1_9_ALIAS
=
"9"
;
public
static
final
String
CLASS_VERSION_10
=
"10"
;
public
static
final
String
ACC_PUBLIC
=
"public"
;
public
static
final
String
ACC_PRIVATE
=
"private"
;
...
...
@@ -92,4 +93,4 @@ public interface JavaConstants
public
static
final
String
TYPE_LONG
=
"long"
;
public
static
final
String
TYPE_DOUBLE
=
"double"
;
public
static
final
String
TYPE_ARRAY
=
"[]"
;
}
\ No newline at end of file
}
core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
View file @
89a9f2bf
...
...
@@ -23,7 +23,6 @@ package proguard.classfile.attribute.visitor;
import
proguard.classfile.Clazz
;
import
proguard.classfile.attribute.BootstrapMethodInfo
;
/**
* This interface specifies the methods for a visitor of
* <code>BootstrapMethodInfo</code> objects. Note that there is only a single
...
...
core/src/proguard/classfile/constant/visitor/BootstrapMethodArgumentVisitor.java
→
core/src/proguard/classfile/constant/visitor/
All
BootstrapMethodArgumentVisitor.java
View file @
89a9f2bf
...
...
@@ -28,19 +28,18 @@ import proguard.classfile.attribute.visitor.BootstrapMethodInfoVisitor;
* This BootstrapMethodInfoVisitor lets a given ConstantVisitor visit all
* constant pool entries of the bootstrap methods it visits.
*
*
* @author Eric Lafortune
*/
public
class
BootstrapMethodArgumentVisitor
public
class
All
BootstrapMethodArgumentVisitor
implements
BootstrapMethodInfoVisitor
{
private
ConstantVisitor
constantVisitor
;
/**
* Creates a new BootstrapMethodArgumentVisitor that will delegate to
the
* given constant visitor.
* Creates a new
All
BootstrapMethodArgumentVisitor that will delegate to
*
the
given constant visitor.
*/
public
BootstrapMethodArgumentVisitor
(
ConstantVisitor
constantVisitor
)
public
All
BootstrapMethodArgumentVisitor
(
ConstantVisitor
constantVisitor
)
{
this
.
constantVisitor
=
constantVisitor
;
}
...
...
@@ -50,7 +49,6 @@ implements BootstrapMethodInfoVisitor
public
void
visitBootstrapMethodInfo
(
Clazz
clazz
,
BootstrapMethodInfo
bootstrapMethodInfo
)
{
// Check bootstrap method.
bootstrapMethodInfo
.
methodArgumentsAccept
(
clazz
,
constantVisitor
);
}
}
core/src/proguard/classfile/editor/AccessFixer.java
View file @
89a9f2bf
...
...
@@ -21,8 +21,13 @@
package
proguard.classfile.editor
;
import
proguard.classfile.*
;
import
proguard.classfile.attribute.*
;
import
proguard.classfile.attribute.annotation.*
;
import
proguard.classfile.attribute.annotation.visitor.AllElementValueVisitor
;
import
proguard.classfile.attribute.visitor.*
;
import
proguard.classfile.constant.*
;
import
proguard.classfile.constant.visitor.ConstantVisitor
;
import
proguard.classfile.instruction.*
;
import
proguard.classfile.instruction.visitor.*
;
import
proguard.classfile.util.*
;
import
proguard.classfile.visitor.*
;
...
...
@@ -33,164 +38,155 @@ import proguard.classfile.visitor.*;
* @author Eric Lafortune
*/
public
class
AccessFixer
extends
ReferencedClassVisitor
implements
ClassVisitor
{
private
final
ConstantVisitor
referencedClassStorer
=
new
MyReferencedClassStorer
();
private
final
ClassVisitor
referencedClassFixer
=
new
ReferencedClassVisitor
(
new
MyReferencedClassAccessFixer
());
private
final
ClassVisitor
referencedMemberFixer
=
new
AllMethodVisitor
(
new
AllAttributeVisitor
(
new
AllInstructionVisitor
(
new
MyReferencedMemberVisitor
(
new
MyReferencedMemberAccessFixer
()))));
/**
* Creates a new AccessFixer.
*/
public
AccessFixer
()
{
// Unfortunately, the inner class must be static to be passed to the
// super constructor. We therefore can't let it refer to this class;
// we'll let this class refer to the inner class instead.
super
(
new
MyAccessFixer
());
}
private
final
ClassVisitor
referencedAnnotationMethodFixer
=
new
AllAttributeVisitor
(
true
,
new
AllElementValueVisitor
(
new
MyReferencedMemberVisitor
(
new
MyReferencedMemberAccessFixer
())));
private
final
ClassVisitor
methodHierarchyFixer
=
new
AllMethodVisitor
(
new
MemberAccessFilter
(
0
,
ClassConstants
.
ACC_PRIVATE
|
ClassConstants
.
ACC_STATIC
,
new
InitializerMethodFilter
(
null
,
new
SimilarMemberVisitor
(
false
,
true
,
false
,
true
,
new
MemberAccessFilter
(
0
,
ClassConstants
.
ACC_PRIVATE
|
ClassConstants
.
ACC_STATIC
,
new
MyReferencedMemberAccessFixer
())))));
// Overridden methods for ClassVisitor.
// Fields acting as parameters for the visitors.
public
void
visitProgramClass
(
ProgramClass
programClass
)
{
// Remember the referencing class.
((
MyAccessFixer
)
classVisitor
).
referencingClass
=
programClass
;
private
Clazz
referencingClass
;
private
int
referencingMethodAccessFlags
;
private
Clazz
referencedClass
;
// Start visiting and fixing the referenced classes and class members.
super
.
visitProgramClass
(
programClass
);
}
// Implementations for ClassVisitor.
public
void
visitLibraryClass
(
LibraryClass
libraryClass
)
{}
public
void
visit
LibraryClass
(
LibraryClass
library
Class
)
public
void
visit
ProgramClass
(
ProgramClass
program
Class
)
{
// Remember the referencing class.
((
MyAccessFixer
)
classVisitor
).
referencingClass
=
library
Class
;
referencingClass
=
program
Class
;
// Start visiting and fixing the referenced classes and class members.
super
.
visitLibraryClass
(
libraryClass
);
}
// Fix the referenced classes.
referencedClassFixer
.
visitProgramClass
(
programClass
);
// Fix the referenced class members.
referencedMemberFixer
.
visitProgramClass
(
programClass
);
// Overridden methods for MemberVisitor.
// Fix the referenced annotation methods.
referencedAnnotationMethodFixer
.
visitProgramClass
(
programClass
);
public
void
visitProgramMethod
(
ProgramClass
programClass
,
ProgramMethod
programMethod
)
{
// Fix the referenced classes and class members.
super
.
visitProgramMember
(
programClass
,
programMethod
);
// Fix overridden or implemented methods higher up the hierarchy.
// We can ignore private and static methods and initializers.
if
((
programMethod
.
getAccessFlags
()
&
(
ClassConstants
.
ACC_PRIVATE
|
ClassConstants
.
ACC_STATIC
))
==
0
&&
!
ClassUtil
.
isInitializer
(
programMethod
.
getName
(
programClass
)))
{
programClass
.
hierarchyAccept
(
false
,
true
,
false
,
false
,
new
NamedMethodVisitor
(
programMethod
.
getName
(
programClass
),
programMethod
.
getDescriptor
(
programClass
),
new
MemberAccessFilter
(
0
,
ClassConstants
.
ACC_PRIVATE
|
ClassConstants
.
ACC_STATIC
,
(
MemberVisitor
)
classVisitor
)));
}
// Fix overridden and overriding methods up and down the hierarchy.
// They are referenced implicitly and need to be accessible too.
referencingMethodAccessFlags
=
0
;
referencedClass
=
null
;
methodHierarchyFixer
.
visitProgramClass
(
programClass
);
}
public
void
visitLibraryMethod
(
LibraryClass
libraryClass
,
LibraryMethod
libraryMethod
)
/**
* This ReferencedMemberVisitor is an InstructionVisitor that also
* remembers the access flags of the referencing methods, and the
* referenced class.
*/
private
class
MyReferencedMemberVisitor
extends
ReferencedMemberVisitor
implements
InstructionVisitor
{
// Fix the referenced classes and class members.
super
.
visitLibraryMember
(
libraryClass
,
libraryMethod
);
// Fix overridden or implemented methods higher up the hierarchy.
// We can ignore private and static methods and initializers.
if
((
libraryMethod
.
getAccessFlags
()
&
(
ClassConstants
.
ACC_PRIVATE
|
ClassConstants
.
ACC_STATIC
))
==
0
&&
!
ClassUtil
.
isInitializer
(
libraryMethod
.
getName
(
libraryClass
)))
public
MyReferencedMemberVisitor
(
MemberVisitor
memberVisitor
)
{
libraryClass
.
hierarchyAccept
(
false
,
true
,
false
,
false
,
new
NamedMethodVisitor
(
libraryMethod
.
getName
(
libraryClass
),
libraryMethod
.
getDescriptor
(
libraryClass
),
new
MemberAccessFilter
(
0
,
ClassConstants
.
ACC_PRIVATE
|
ClassConstants
.
ACC_STATIC
,
(
MemberVisitor
)
classVisitor
)));
super
(
memberVisitor
);
}
}
//
Overridden method
s for
Co
nst
ant
Visitor.
//
Implementation
s for
I
nst
ruction
Visitor.
public
void
visitStringConstant
(
Clazz
clazz
,
StringConstant
stringConstant
)
{
// Fix the access flags of the referenced class, if any.
super
.
visitStringConstant
(
clazz
,
stringConstant
);
// Fix the access flags of the referenced class member, if any.
stringConstant
.
referencedMemberAccept
((
MemberVisitor
)
classVisitor
);
}
public
void
visitAnyInstruction
(
Clazz
clazz
,
Method
method
,
CodeAttribute
codeAttribute
,
int
offset
,
Instruction
instruction
)
{}
public
void
visitAnyRefConstant
(
Clazz
clazz
,
RefConstant
refConstant
)
{
// Remember the referenced class. Note that we're interested in the
// class of the invocation, not in the class in which the member was
// actually found, unless it is an array type.
if
(
ClassUtil
.
isInternalArrayType
(
refConstant
.
getClassName
(
clazz
)))
public
void
visitConstantInstruction
(
Clazz
clazz
,
Method
method
,
CodeAttribute
codeAttribute
,
int
offset
,
ConstantInstruction
constantInstruction
)
{
// For an array type, the class will be java.lang.Object.
((
MyAccessFixer
)
classVisitor
).
referencedClass
=
refConstant
.
referencedClass
;
}
else
{
// Remember the referenced class.
clazz
.
constantPoolEntryAccept
(
refConstant
.
u2classIndex
,
referencedClassStorer
);
// Remember the access flags.
referencingMethodAccessFlags
=
method
.
getAccessFlags
();
// Fix the referenced classes and class members.
clazz
.
constantPoolEntryAccept
(
constantInstruction
.
constantIndex
,
this
);
}
// Fix the access flags of the class of the referenced class member.
super
.
visitAnyRefConstant
(
clazz
,
refConstant
);
// Fix the access flags of the referenced class member.
refConstant
.
referencedMemberAccept
((
MemberVisitor
)
classVisitor
);
}
// Overridden methods for ConstantVisitor.
public
void
visitAnyRefConstant
(
Clazz
clazz
,
RefConstant
refConstant
)
{
// Remember the referenced class. Note that we're interested in the
// class of the invocation, not in the class in which the member was
// actually found, unless it is an array type.
if
(
ClassUtil
.
isInternalArrayType
(
refConstant
.
getClassName
(
clazz
)))
{
// For an array type, the class will be java.lang.Object.
referencedClass
=
refConstant
.
referencedClass
;
}
else
{
// Remember the referenced class.
clazz
.
constantPoolEntryAccept
(
refConstant
.
u2classIndex
,
this
);
}
// Fix the access flags of referenced class member.
super
.
visitAnyRefConstant
(
clazz
,
refConstant
);
}
/**
* This ConstantVisitor stores the classes referenced by the class
* constants that it visits.
*/
private
class
MyReferencedClassStorer
extends
SimplifiedVisitor
implements
ConstantVisitor
{
// Implementations for ConstantVisitor.
public
void
visitClassConstant
(
Clazz
clazz
,
ClassConstant
classConstant
)
{
// Remember the referenced class.
((
MyAccessFixer
)
classVisitor
).
referencedClass
=
classConstant
.
referencedClass
;
referencedClass
=
classConstant
.
referencedClass
;
}
// Implementations for ElementValueVisitor.
public
void
visitAnyElementValue
(
Clazz
clazz
,
Annotation
annotation
,
ElementValue
elementValue
)
{
// Set the referencing access flags and set the referenced class.
referencingMethodAccessFlags
=
ClassConstants
.
ACC_STATIC
;
referencedClass
=
elementValue
.
referencedClass
;
// Fix the access flags of referenced annotation method.
super
.
visitAnyElementValue
(
clazz
,
annotation
,
elementValue
);
}
}
/**
* This ClassVisitor and MemberVisitor fixes the access flags of the
* classes and class members that it visits, relative to the referencing
* class.
*
* This class must be static so it can be passed to the super constructor
* of the outer class.
* This ClassVisitor fixes the access flags of the classes that it visits,
* relative to the referencing class.
*/
private
static
class
MyAccessFixer
extends
SimplifiedVisitor
implements
ClassVisitor
,
MemberVisitor
private
class
MyReferencedClassAccessFixer
extends
SimplifiedVisitor
implements
ClassVisitor
,
AttributeVisitor
,
InnerClassesInfoVisitor
{
private
Clazz
referencingClass
;
private
Clazz
referencedClass
;
// Implementations for ClassVisitor.
public
void
visitLibraryClass
(
LibraryClass
libraryClass
)
{}
...
...
@@ -198,25 +194,86 @@ implements ClassVisitor
public
void
visitProgramClass
(
ProgramClass
programClass
)
{
// Do we need to update the access flags?
int
currentAccessFlags
=
programClass
.
getAccessFlags
();
int
currentAccessLevel
=
AccessUtil
.
accessLevel
(
currentAccessFlags
);
if
(
currentAccessLevel
<
AccessUtil
.
PUBLIC
)
{
// Compute the required access level.
int
requiredAccessLevel
=
inSamePackage
(
programClass
,
referencingClass
)
?
AccessUtil
.
PACKAGE_VISIBLE
:
AccessUtil
.
PUBLIC
;
// Fix the class access flags if necessary.
if
(
currentAccessLevel
<
requiredAccessLevel
)
{
programClass
.
u2accessFlags
=
AccessUtil
.
replaceAccessFlags
(
currentAccessFlags
,
AccessUtil
.
accessFlags
(
requiredAccessLevel
));
}
}
// Also check the InnerClasses attribute, if any.
programClass
.
attributesAccept
(
this
);
}
// Implementations for AttributeVisitor.
public
void
visitAnyAttribute
(
Clazz
clazz
,
Attribute
attribute
)
{}
// Compute the required access level.
int
requiredAccessLevel
=
inSamePackage
(
programClass
,
referencingClass
)
?
AccessUtil
.
PACKAGE_VISIBLE
:
AccessUtil
.
PUBLIC
;
// Fix the class access flags if necessary.
if
(
currentAccessLevel
<
requiredAccessLevel
)
public
void
visitInnerClassesAttribute
(
Clazz
clazz
,
InnerClassesAttribute
innerClassesAttribute
)
{
innerClassesAttribute
.
innerClassEntriesAccept
(
clazz
,
this
);
}
// Implementations for InnerClassesInfoVisitor.
public
void
visitInnerClassesInfo
(
Clazz
clazz
,
InnerClassesInfo
innerClassesInfo
)
{
// Is this an inner class?
int
innerClassIndex
=
innerClassesInfo
.
u2innerClassIndex
;
if
(
innerClassIndex
!=
0
)
{
programClass
.
u2accessFlags
=
AccessUtil
.
replaceAccessFlags
(
currentAccessFlags
,
AccessUtil
.
accessFlags
(
requiredAccessLevel
));
String
innerClassName
=
clazz
.
getClassName
(
innerClassIndex
);
if
(
innerClassName
.
equals
(
clazz
.
getName
()))
{
// Do we need to update the access flags?
int
currentAccessFlags
=
innerClassesInfo
.
u2innerClassAccessFlags
;
int
currentAccessLevel
=
AccessUtil
.
accessLevel
(
currentAccessFlags
);
if
(
currentAccessLevel
<
AccessUtil
.
PUBLIC
)
{
// Compute the required access level.
int
requiredAccessLevel
=
inSamePackage
(
clazz
,
referencingClass
)
?
AccessUtil
.
PACKAGE_VISIBLE
:
AccessUtil
.
PUBLIC
;
// Fix the inner class access flags if necessary.
if
(
currentAccessLevel
<
requiredAccessLevel
)
{
innerClassesInfo
.
u2innerClassAccessFlags
=
AccessUtil
.
replaceAccessFlags
(
currentAccessFlags
,
AccessUtil
.
accessFlags
(
requiredAccessLevel
));
}
}
}
}
}
}
/**
* This MemberVisitor fixes the access flags of the class members that it
* visits, relative to the referencing class and method.
*/
private
class
MyReferencedMemberAccessFixer
extends
SimplifiedVisitor
implements
MemberVisitor
{
// Implementations for MemberVisitor.
public
void
visitLibraryMember
(
LibraryClass
libraryClass
,
LibraryMember
libraryMember
)
{}
...
...
@@ -224,39 +281,44 @@ implements ClassVisitor
public
void
visitProgramMember
(
ProgramClass
programClass
,
ProgramMember
programMember
)
{
// Do we need to update the access flags?
int
currentAccessFlags
=
programMember
.
getAccessFlags
();
int
currentAccessLevel
=
AccessUtil
.
accessLevel
(
currentAccessFlags
);
// Compute the required access level.
// For protected access, we're taking into account the class in the
// invocation and the class that actually contains the member.
int
requiredAccessLevel
=
programClass
.
equals
(
referencingClass
)
?
AccessUtil
.
PRIVATE
:
inSamePackage
(
programClass
,
referencingClass
)
?
AccessUtil
.
PACKAGE_VISIBLE
:
referencedClass
!=
null
&&
referencingClass
.
extends_
(
referencedClass
)
&&
referencingClass
.
extends_
(
programClass
)
?
AccessUtil
.
PROTECTED
:
AccessUtil
.
PUBLIC
;
// Fix the class member access flags if necessary.
if
(
currentAccessLevel
<
requiredAccessLevel
)
if
(
currentAccessLevel
<
AccessUtil
.
PUBLIC
)
{
programMember
.
u2accessFlags
=
AccessUtil
.
replaceAccessFlags
(
currentAccessFlags
,
AccessUtil
.
accessFlags
(
requiredAccessLevel
));
// Compute the required access level.
// For protected access, the referencing method may not be
// static. We're also taking into account the class in the
// invocation and the class that actually contains the member.
int
requiredAccessLevel
=
programClass
.
equals
(
referencingClass
)
?
AccessUtil
.
PRIVATE
:
inSamePackage
(
programClass
,
referencingClass
)
?
AccessUtil
.
PACKAGE_VISIBLE
:
(
referencingMethodAccessFlags
&
ClassConstants
.
ACC_STATIC
)
==
0
&&
(
referencedClass
==
null
||
referencingClass
.
extends_
(
referencedClass
))
&&
referencingClass
.
extends_
(
programClass
)
?
AccessUtil
.
PROTECTED
:
AccessUtil
.
PUBLIC
;
// Fix the class member access flags if necessary.
if
(
currentAccessLevel
<
requiredAccessLevel
)
{
programMember
.
u2accessFlags
=
AccessUtil
.
replaceAccessFlags
(
currentAccessFlags
,
AccessUtil
.
accessFlags
(
requiredAccessLevel
));
}
}
}
}
// Small utility methods.
// Small utility methods.
/**
* Returns whether the two given classes are in the same package.
*/
private
boolean
inSamePackage
(
Clazz
class1
,
Clazz
class2
)
{
return
ClassUtil
.
internalPackageName
(
class1
.
getName
()).
equals
(
ClassUtil
.
internalPackageName
(
class2
.
getName
()));
}
/**
* Returns whether the two given classes are in the same package.
*/
private
boolean
inSamePackage
(
Clazz
class1
,
Clazz
class2
)
{
return
ClassUtil
.
internalPackageName
(
class1
.
getName
()).
equals
(
ClassUtil
.
internalPackageName
(
class2
.
getName
()));
}
}
core/src/proguard/classfile/util/ClassUtil.java
View file @
89a9f2bf
...
...
@@ -106,6 +106,7 @@ public class ClassUtil
externalClassVersion
.
equals
(
JavaConstants
.
CLASS_VERSION_1_8
)
?
ClassConstants
.
CLASS_VERSION_1_8
:
externalClassVersion
.
equals
(
JavaConstants
.
CLASS_VERSION_1_9_ALIAS
)
||
externalClassVersion
.
equals
(
JavaConstants
.
CLASS_VERSION_1_9
)
?
ClassConstants
.
CLASS_VERSION_1_9
:
externalClassVersion
.
equals
(
JavaConstants
.
CLASS_VERSION_10
)
?
ClassConstants
.
CLASS_VERSION_10
:
0
;
}
...
...
@@ -128,6 +129,7 @@ public class ClassUtil
case
ClassConstants
.
CLASS_VERSION_1_7
:
return
JavaConstants
.
CLASS_VERSION_1_7
;
case
ClassConstants
.
CLASS_VERSION_1_8
:
return
JavaConstants
.
CLASS_VERSION_1_8
;
case
ClassConstants
.
CLASS_VERSION_1_9
:
return
JavaConstants
.
CLASS_VERSION_1_9
;
case
ClassConstants
.
CLASS_VERSION_10
:
return
JavaConstants
.
CLASS_VERSION_10
;
default
:
return
null
;
}
}
...
...
@@ -141,14 +143,14 @@ public class ClassUtil
public
static
void
checkVersionNumbers
(
int
internalClassVersion
)
throws
UnsupportedOperationException
{
if
(
internalClassVersion
<
ClassConstants
.
CLASS_VERSION_1_0
||
internalClassVersion
>
ClassConstants
.
CLASS_VERSION_1
_9
)
internalClassVersion
>
ClassConstants
.
CLASS_VERSION_1
0
)
{
throw
new
UnsupportedOperationException
(
"Unsupported version number ["
+
internalMajorClassVersion
(
internalClassVersion
)+
"."
+
internalMinorClassVersion
(
internalClassVersion
)+
"] (maximum "
+
ClassConstants
.
CLASS_VERSION_1
_9
_MAJOR
+
"."
+
ClassConstants
.
CLASS_VERSION_1
_9
_MINOR
+
", Java "
+
JavaConstants
.
CLASS_VERSION_1
_9
+
")"
);
ClassConstants
.
CLASS_VERSION_1
0
_MAJOR
+
"."
+
ClassConstants
.
CLASS_VERSION_1
0
_MINOR
+
", Java "
+
JavaConstants
.
CLASS_VERSION_1
0
+
")"
);
}
}
...
...
core/src/proguard/classfile/visitor/MultiConstantVisitor.java
0 → 100644
View file @
89a9f2bf
/*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2018 GuardSquare NV
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package
proguard.classfile.visitor
;
import
proguard.classfile.*
;
import
proguard.classfile.constant.*
;
import
proguard.classfile.constant.visitor.ConstantVisitor
;
import
proguard.classfile.util.SimplifiedVisitor
;
import
proguard.util.ArrayUtil
;
/**
* This ConstantVisitor delegates all visits to each ConstantVisitor in a given list.
*
* @author Johan Leys
*/
public
class
MultiConstantVisitor
extends
SimplifiedVisitor
implements
ConstantVisitor
{
private
ConstantVisitor
[]
constantVisitors
;
private
int
constantVisitorCount
;
public
MultiConstantVisitor
()
{
this
.
constantVisitors
=
new
ConstantVisitor
[
16
];
}
public
MultiConstantVisitor
(
ConstantVisitor
...
constantVisitors
)
{
this
.
constantVisitors
=
constantVisitors
;
this
.
constantVisitorCount
=
this
.
constantVisitors
.
length
;
}
public
void
addClassVisitor
(
ConstantVisitor
constantVisitor
)
{
constantVisitors
=
ArrayUtil
.
add
(
constantVisitors
,
constantVisitorCount
++,
constantVisitor
);
}
// Implementations for ConstantVisitor.
public
void
visitAnyConstant
(
Clazz
clazz
,
Constant
constant
)
{
for
(
int
index
=
0
;
index
<
constantVisitorCount
;
index
++)
{
constant
.
accept
(
clazz
,
constantVisitors
[
index
]);
}
}
}
core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
View file @
89a9f2bf
...
...
@@ -38,7 +38,7 @@ extends SimplifiedVisitor
implements
ConstantVisitor
,
ElementValueVisitor
{
pr
ivate
final
MemberVisitor
memberVisitor
;
pr
otected
final
MemberVisitor
memberVisitor
;
public
ReferencedMemberVisitor
(
MemberVisitor
memberVisitor
)
...
...
core/src/proguard/classfile/visitor/SimilarMemberVisitor.java
View file @
89a9f2bf
...
...
@@ -25,7 +25,7 @@ import proguard.classfile.*;
/**
* This <code>MemberVisitor</code> lets a given <code>MemberVisitor</code>
* visit all members that have the same name and type as the visited methods
* in the class hierarchy of a given target class.
* in the class hierarchy of
the members' classes or of
a given target class.
*
* @author Eric Lafortune
*/
...
...
@@ -40,6 +40,37 @@ implements MemberVisitor
private
final
MemberVisitor
memberVisitor
;
/**
* Creates a new SimilarMemberVisitor.
* @param visitThisMember specifies whether to visit the class
* members in the members' classes themselves.
* @param visitSuperMembers specifies whether to visit the class
* members in the super classes of the
* members' classes.
* @param visitInterfaceMembers specifies whether to visit the class
* members in the interface classes of the
* members' classes.
* @param visitOverridingMembers specifies whether to visit the class
* members in the subclasses of the members'
* classes.
* @param memberVisitor the <code>MemberVisitor</code> to which
* visits will be delegated.
*/
public
SimilarMemberVisitor
(
boolean
visitThisMember
,
boolean
visitSuperMembers
,
boolean
visitInterfaceMembers
,
boolean
visitOverridingMembers
,
MemberVisitor
memberVisitor
)
{
this
(
null
,
visitThisMember
,
visitSuperMembers
,
visitInterfaceMembers
,
visitOverridingMembers
,
memberVisitor
);
}
/**
* Creates a new SimilarMemberVisitor.
* @param targetClass the class in whose hierarchy to look for
...
...
@@ -78,6 +109,8 @@ implements MemberVisitor
public
void
visitProgramField
(
ProgramClass
programClass
,
ProgramField
programField
)
{
Clazz
targetClass
=
targetClass
(
programClass
);
targetClass
.
hierarchyAccept
(
visitThisMember
,
visitSuperMembers
,
visitInterfaceMembers
,
...
...
@@ -90,6 +123,8 @@ implements MemberVisitor
public
void
visitLibraryField
(
LibraryClass
libraryClass
,
LibraryField
libraryField
)
{
Clazz
targetClass
=
targetClass
(
libraryClass
);
targetClass
.
hierarchyAccept
(
visitThisMember
,
visitSuperMembers
,
visitInterfaceMembers
,
...
...
@@ -102,6 +137,8 @@ implements MemberVisitor
public
void
visitProgramMethod
(
ProgramClass
programClass
,
ProgramMethod
programMethod
)
{
Clazz
targetClass
=
targetClass
(
programClass
);
targetClass
.
hierarchyAccept
(
visitThisMember
,
visitSuperMembers
,
visitInterfaceMembers
,
...
...
@@ -114,6 +151,8 @@ implements MemberVisitor
public
void
visitLibraryMethod
(
LibraryClass
libraryClass
,
LibraryMethod
libraryMethod
)
{
Clazz
targetClass
=
targetClass
(
libraryClass
);
targetClass
.
hierarchyAccept
(
visitThisMember
,
visitSuperMembers
,
visitInterfaceMembers
,
...
...
@@ -122,4 +161,14 @@ implements MemberVisitor
libraryMethod
.
getDescriptor
(
libraryClass
),
memberVisitor
));
}
/**
* Returns the target class, or the given class if the target class is
* null.
*/
private
Clazz
targetClass
(
Clazz
clazz
)
{
return
targetClass
!=
null
?
targetClass
:
clazz
;
}
}
\ No newline at end of file
core/src/proguard/io/JarWriter.java
View file @
89a9f2bf
...
...
@@ -26,7 +26,8 @@ import java.io.*;
import
java.util.Date
;
/**
* This DataEntryWriter sends data entries to a given jar/zip file.
* This DataEntryWriter sends data entries to a the jar/zip files specified by
* their parents.
*
* @author Eric Lafortune
*/
...
...
Prev
1
2
Next