diff options
Diffstat (limited to 'src/main')
19 files changed, 177 insertions, 34 deletions
diff --git a/src/main/META-INF/MANIFEST.MF b/src/main/META-INF/MANIFEST.MF index 8464fca1..b53b6e37 100644 --- a/src/main/META-INF/MANIFEST.MF +++ b/src/main/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Specification-Title: Javassist Specification-Vendor: Shigeru Chiba, www.javassist.org -Specification-Version: 3.26.0-GA +Specification-Version: 3.29.0-SNAPSHOT Main-Class: javassist.CtClass Automatic-Module-Name: org.javassist diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index a215246b..f1a47342 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -69,7 +69,7 @@ public abstract class CtClass { /** * The version number of this release. */ - public static final String version = "3.26.0-GA"; + public static final String version = "3.29.0-SNAPSHOT"; /** * Prints the version number and the copyright notice. @@ -80,7 +80,7 @@ public abstract class CtClass { */ public static void main(String[] args) { System.out.println("Javassist version " + CtClass.version); - System.out.println("Copyright (C) 1999-2019 Shigeru Chiba." + System.out.println("Copyright (C) 1999-2021 Shigeru Chiba." + " All Rights Reserved."); } @@ -1423,7 +1423,7 @@ public abstract class CtClass { public void detach() { ClassPool cp = getClassPool(); CtClass obj = cp.removeCached(getName()); - if (obj != this) + if (obj != null && obj != this) cp.cacheCtClass(getName(), obj, false); } diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index ae196c4a..959ec302 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -179,6 +179,7 @@ class CtClassType extends CtClass { } public ClassFile getClassFile3(boolean doCompress) { + // quick path - no locking ClassFile cfile = classfile; if (cfile != null) return cfile; @@ -186,17 +187,29 @@ class CtClassType extends CtClass { if (doCompress) classPool.compress(); - if (rawClassfile != null) { + byte[] rcfile; + synchronized (this) { + // repeat under lock to make sure we get a consistent result (classfile might have been set by another thread) + cfile = classfile; + if (cfile != null) + return cfile; + + rcfile = rawClassfile; + } + + if (rcfile != null) { + final ClassFile cf; try { - ClassFile cf = new ClassFile(new DataInputStream( - new ByteArrayInputStream(rawClassfile))); - rawClassfile = null; - getCount = GET_THRESHOLD; - return setClassFile(cf); + cf = new ClassFile(new DataInputStream(new ByteArrayInputStream(rcfile))); } catch (IOException e) { throw new RuntimeException(e.toString(), e); } + getCount = GET_THRESHOLD; + synchronized (this) { + rawClassfile = null; + return setClassFile(cf); + } } InputStream fin = null; diff --git a/src/main/javassist/Loader.java b/src/main/javassist/Loader.java index 37f83d68..27447d38 100644 --- a/src/main/javassist/Loader.java +++ b/src/main/javassist/Loader.java @@ -444,6 +444,7 @@ public class Loader extends ClassLoader { if (doDelegation) if (name.startsWith("java.") || name.startsWith("javax.") + || name.startsWith("jdk.internal.") || name.startsWith("sun.") || name.startsWith("com.sun.") || name.startsWith("org.w3c.") diff --git a/src/main/javassist/bytecode/AnnotationDefaultAttribute.java b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java index 43021ecf..8c7084c0 100644 --- a/src/main/javassist/bytecode/AnnotationDefaultAttribute.java +++ b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java @@ -117,6 +117,28 @@ public class AnnotationDefaultAttribute extends AttributeInfo { } } + @Override + void renameClass(String oldname, String newname) { + try { + MemberValue defaultValue = getDefaultValue(); + defaultValue.renameClass(oldname, newname); + setDefaultValue(defaultValue); + } catch (Exception e) { + // ignore + } + } + + @Override + void renameClass(Map<String, String> classnames) { + try { + MemberValue defaultValue = getDefaultValue(); + defaultValue.renameClass(classnames); + setDefaultValue(defaultValue); + } catch (Exception e) { + // ignore + } + } + /** * Obtains the default value represented by this attribute. */ diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java index be6e2a21..3aa0bd31 100644 --- a/src/main/javassist/bytecode/AttributeInfo.java +++ b/src/main/javassist/bytecode/AttributeInfo.java @@ -254,7 +254,7 @@ public class AttributeInfo { /* The following two methods are used to implement * ClassFile.renameClass(). * Only CodeAttribute, LocalVariableAttribute, - * AnnotationsAttribute, and SignatureAttribute + * AnnotationDefaultAttribute, AnnotationsAttribute, and SignatureAttribute * override these methods. */ void renameClass(String oldname, String newname) {} diff --git a/src/main/javassist/bytecode/LocalVariableAttribute.java b/src/main/javassist/bytecode/LocalVariableAttribute.java index a0a62cc3..3f35e440 100644 --- a/src/main/javassist/bytecode/LocalVariableAttribute.java +++ b/src/main/javassist/bytecode/LocalVariableAttribute.java @@ -218,6 +218,22 @@ public class LocalVariableAttribute extends AttributeInfo { } /** + * Returns the name of the local variable with given index. + * If you want to get the parameter name of method with correct order, + * you should using this method. + * + * @param index the index of the local variable. + */ + public String variableNameByIndex(int index) { + for (int i = 0; i < tableLength(); i++) { + if (index(i) == index) { + return variableName(i); + } + } + throw new ArrayIndexOutOfBoundsException(); + } + + /** * Returns the value of * <code>local_variable_table[i].descriptor_index</code>. * This represents the type descriptor of the local variable. diff --git a/src/main/javassist/bytecode/MethodParametersAttribute.java b/src/main/javassist/bytecode/MethodParametersAttribute.java index 12521095..b9c252a9 100644 --- a/src/main/javassist/bytecode/MethodParametersAttribute.java +++ b/src/main/javassist/bytecode/MethodParametersAttribute.java @@ -57,6 +57,14 @@ public class MethodParametersAttribute extends AttributeInfo { } /** + * Returns the name of the i-th element of <code>parameters</code>. + * @param i the position of the parameter. + */ + public String parameterName(int i) { + return getConstPool().getUtf8Info(name(i)); + } + + /** * Returns the value of <code>access_flags</code> of the i-th element of <code>parameters</code>. * * @param i the position of the parameter. diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java index 15dbd56c..c17b3f29 100644 --- a/src/main/javassist/bytecode/SignatureAttribute.java +++ b/src/main/javassist/bytecode/SignatureAttribute.java @@ -150,8 +150,9 @@ public class SignatureAttribute extends AttributeInfo { } } catch (IndexOutOfBoundsException e) { break; } - nameBufs.add(nameBuf); - genericParamBufs.add(genericParamBuf); + + nameBufs.add(nameBuf); + genericParamBufs.add(genericParamBuf); i = k + 1; String name = String.join("$", nameBufs.toArray(new StringBuilder[0])); diff --git a/src/main/javassist/bytecode/StackMapTable.java b/src/main/javassist/bytecode/StackMapTable.java index 9b8e5fae..62a6aca0 100644 --- a/src/main/javassist/bytecode/StackMapTable.java +++ b/src/main/javassist/bytecode/StackMapTable.java @@ -204,8 +204,11 @@ public class StackMapTable extends AttributeInfo { } else if (type < 128) pos = sameLocals(pos, type); - else if (type < 247) - throw new BadBytecode("bad frame_type in StackMapTable"); + else if (type < 247) { + throw new BadBytecode( + "bad frame_type " + type + " in StackMapTable (pos: " + + pos + ", frame no.:" + nth + ")"); + } else if (type == 247) // SAME_LOCALS_1_STACK_ITEM_EXTENDED pos = sameLocals(pos, type); else if (type < 251) { @@ -881,16 +884,21 @@ public class StackMapTable extends AttributeInfo { position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1); boolean match; if (exclusive) - match = oldPos < where && where <= position; + // We optimize this expression by hand: + // match = (oldPos == 0 && where == 0 && (0 < position || 0 == position)) + // || oldPos < where && where <= position; + match = (oldPos == 0 && where == 0) + || oldPos < where && where <= position; else match = oldPos <= where && where < position; if (match) { + int current = info[pos] & 0xff; int newDelta = offsetDelta + gap; position += gap; if (newDelta < 64) info[pos] = (byte)(newDelta + base); - else if (offsetDelta < 64) { + else if (offsetDelta < 64 && current != entry) { byte[] newinfo = insertGap(info, pos, 2); newinfo[pos] = (byte)entry; ByteArray.write16bit(newDelta, newinfo, pos + 1); @@ -931,7 +939,8 @@ public class StackMapTable extends AttributeInfo { position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1); boolean match; if (exclusive) - match = oldPos < where && where <= position; + match = (oldPos == 0 && where == 0) + || oldPos < where && where <= position; else match = oldPos <= where && where < position; diff --git a/src/main/javassist/bytecode/analysis/Type.java b/src/main/javassist/bytecode/analysis/Type.java index db02df35..33dc81f3 100644 --- a/src/main/javassist/bytecode/analysis/Type.java +++ b/src/main/javassist/bytecode/analysis/Type.java @@ -15,9 +15,7 @@ */ package javassist.bytecode.analysis; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Map; +import java.util.*; import javassist.ClassPool; import javassist.CtClass; @@ -496,24 +494,26 @@ public class Type { if (typeMap == null||typeMap.isEmpty()) alterMap.clear(); - for (String name:alterMap.keySet()) + Iterator<String> it = alterMap.keySet().iterator(); + while (it.hasNext()) { + String name = it.next(); if (!typeMap.containsKey(name)) - alterMap.remove(name); + it.remove(); + } // Reduce to subinterfaces // This does not need to be recursive since we make a copy, // and that copy contains all super types for the whole hierarchy - for (CtClass intf:alterMap.values()) { - CtClass[] interfaces; + Collection<CtClass> interfaces = new ArrayList<>(); + for (CtClass intf : alterMap.values()) { try { - interfaces = intf.getInterfaces(); + interfaces.addAll(Arrays.asList(intf.getInterfaces())); } catch (NotFoundException e) { throw new RuntimeException(e); } - - for (CtClass c:interfaces) - alterMap.remove(c.getName()); } + for (CtClass c : interfaces) + alterMap.remove(c.getName()); return alterMap; } diff --git a/src/main/javassist/bytecode/annotation/ArrayMemberValue.java b/src/main/javassist/bytecode/annotation/ArrayMemberValue.java index d1eeb271..f6bc6150 100644 --- a/src/main/javassist/bytecode/annotation/ArrayMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ArrayMemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.ConstPool; @@ -87,6 +88,30 @@ public class ArrayMemberValue extends MemberValue { return a.getClass(); } + @Override + public void renameClass(String oldname, String newname) { + if (type != null) { + type.renameClass(oldname, newname); + } + if (values != null) { + for (MemberValue value : values) { + value.renameClass(oldname, newname); + } + } + } + + @Override + public void renameClass(Map<String, String> classnames) { + if (type != null) { + type.renameClass(classnames); + } + if (values != null) { + for (MemberValue value : values) { + value.renameClass(classnames); + } + } + } + /** * Obtains the type of the elements. * diff --git a/src/main/javassist/bytecode/annotation/ClassMemberValue.java b/src/main/javassist/bytecode/annotation/ClassMemberValue.java index e9fd7ec4..495a1e2a 100644 --- a/src/main/javassist/bytecode/annotation/ClassMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ClassMemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.BadBytecode; @@ -95,6 +96,20 @@ public class ClassMemberValue extends MemberValue { return loadClass(cl, "java.lang.Class"); } + @Override + public void renameClass(String oldname, String newname) { + String value = cp.getUtf8Info(valueIndex); + String newValue = Descriptor.rename(value, oldname, newname); + setValue(Descriptor.toClassName(newValue)); + } + + @Override + public void renameClass(Map<String, String> classnames) { + String value = cp.getUtf8Info(valueIndex); + String newValue = Descriptor.rename(value, classnames); + setValue(Descriptor.toClassName(newValue)); + } + /** * Obtains the value of the member. * diff --git a/src/main/javassist/bytecode/annotation/EnumMemberValue.java b/src/main/javassist/bytecode/annotation/EnumMemberValue.java index a0a4e036..0f37178a 100644 --- a/src/main/javassist/bytecode/annotation/EnumMemberValue.java +++ b/src/main/javassist/bytecode/annotation/EnumMemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.ConstPool; @@ -76,6 +77,20 @@ public class EnumMemberValue extends MemberValue { return loadClass(cl, getType()); } + @Override + public void renameClass(String oldname, String newname) { + String type = cp.getUtf8Info(typeIndex); + String newType = Descriptor.rename(type, oldname, newname); + setType(Descriptor.toClassName(newType)); + } + + @Override + public void renameClass(Map<String, String> classnames) { + String type = cp.getUtf8Info(typeIndex); + String newType = Descriptor.rename(type, classnames); + setType(Descriptor.toClassName(newType)); + } + /** * Obtains the enum type name. * diff --git a/src/main/javassist/bytecode/annotation/MemberValue.java b/src/main/javassist/bytecode/annotation/MemberValue.java index da99885c..0f132a83 100644 --- a/src/main/javassist/bytecode/annotation/MemberValue.java +++ b/src/main/javassist/bytecode/annotation/MemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.ConstPool; @@ -74,6 +75,14 @@ public abstract class MemberValue { return classname; } + /* The following two methods are used to implement + * ClassFile.renameClass(). + * Only ArrayMemberValue, ClassMemberValue, EnumMemberValue + * override these methods. + */ + public void renameClass(String oldname, String newname) {} + public void renameClass(Map<String, String> classnames) {} + /** * Accepts a visitor. */ diff --git a/src/main/javassist/bytecode/stackmap/TypeData.java b/src/main/javassist/bytecode/stackmap/TypeData.java index 9bc837d3..4762eb85 100644 --- a/src/main/javassist/bytecode/stackmap/TypeData.java +++ b/src/main/javassist/bytecode/stackmap/TypeData.java @@ -206,7 +206,12 @@ public abstract class TypeData { } @Override - public boolean eq(TypeData d) { return getName().equals(d.getName()); } + public boolean eq(TypeData d) { + if (d.isUninit()) + return d.eq(this); + else + return getName().equals(d.getName()); + } } /* a type variable representing a class type or a basic type. @@ -853,7 +858,12 @@ public abstract class TypeData { } @Override - public boolean eq(TypeData d) { return name.equals(d.getName()); } + public boolean eq(TypeData d) { + if (d.isUninit()) + return d.eq(this); + else + return name.equals(d.getName()); + } @Override public void setType(String typeName, ClassPool cp) throws BadBytecode {} diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index 48acd137..e8e9912b 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -648,7 +648,7 @@ public class MemberCodeGen extends CodeGen { throw new CompileError("no such constructor: " + targetClass.getName()); if (declClass != thisClass && AccessFlag.isPrivate(acc)) { - if (declClass.getClassFile().getMajorVersion() < ClassFile.JAVA_11 + if (declClass.getClassFile().getMajorVersion() < ClassFile.JAVA_8 || !isFromSameDeclaringClass(declClass, thisClass)) { desc = getAccessibleConstructor(desc, declClass, minfo); bytecode.addOpcode(Opcode.ACONST_NULL); // the last parameter diff --git a/src/main/javassist/compiler/TypeChecker.java b/src/main/javassist/compiler/TypeChecker.java index 9e01d0a1..ec7e3cf3 100644 --- a/src/main/javassist/compiler/TypeChecker.java +++ b/src/main/javassist/compiler/TypeChecker.java @@ -933,7 +933,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { } } - throw new CompileError("bad filed access"); + throw new CompileError("bad field access"); } private CtField fieldAccess2(Expr e, String jvmClassName) throws CompileError { diff --git a/src/main/javassist/util/proxy/SecurityActions.java b/src/main/javassist/util/proxy/SecurityActions.java index c940561b..6873e01b 100755 --- a/src/main/javassist/util/proxy/SecurityActions.java +++ b/src/main/javassist/util/proxy/SecurityActions.java @@ -213,7 +213,6 @@ class SecurityActions extends SecurityManager if (e.getCause() instanceof NoSuchFieldException) throw new ClassNotFoundException("No such instance.", e.getCause()); if (e.getCause() instanceof IllegalAccessException - || e.getCause() instanceof IllegalAccessException || e.getCause() instanceof SecurityException) throw new ClassNotFoundException("Security denied access.", e.getCause()); throw new RuntimeException(e.getCause()); |