asm issueshttps://gitlab.ow2.org/asm/asm/-/issues2017-12-26T09:28:35Zhttps://gitlab.ow2.org/asm/asm/-/issues/317794ClassReader throws an exception while parsing Java 9 module_info.class2017-12-26T09:28:35ZAleksandar SeovicClassReader throws an exception while parsing Java 9 module_info.classI ran into an issue compiling one of my Java 9 modules, with Maven failing during testCompile phase with the following exception:
```
Caused by: java.lang.ArrayIndexOutOfBoundsException: 29
at org.objectweb.asm.ClassReader.readUT...I ran into an issue compiling one of my Java 9 modules, with Maven failing during testCompile phase with the following exception:
```
Caused by: java.lang.ArrayIndexOutOfBoundsException: 29
at org.objectweb.asm.ClassReader.readUTF8(ClassReader.java:2591)
at org.objectweb.asm.ClassReader.readStringish(ClassReader.java:2659)
at org.objectweb.asm.ClassReader.readModule(ClassReader.java:2693)
at org.objectweb.asm.ClassReader.readModule(ClassReader.java:726)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:632)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at org.codehaus.plexus.languages.java.jpms.AsmModuleInfoParser.parse(AsmModuleInfoParser.java:81)
at org.codehaus.plexus.languages.java.jpms.AsmModuleInfoParser.getModuleDescriptor(AsmModuleInfoParser.java:65)
at org.codehaus.plexus.languages.java.jpms.LocationManager.resolvePaths(LocationManager.java:113)
at org.apache.maven.plugin.compiler.TestCompilerMojo.preparePaths(TestCompilerMojo.java:281)
at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:762)
at org.apache.maven.plugin.compiler.TestCompilerMojo.execute(TestCompilerMojo.java:176)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
```
There is more, and you can see the full stack trace in [MCOMPILER-309](https://issues.apache.org/jira/projects/MCOMPILER/issues/MCOMPILER-309), but I believe the above is most relevant.
On suggestion from the Maven team I've upgraded ASM version used by `maven-compiler-plugin` to 6.0, but that didn't help and I'm still seeing the exact same exception as before.
Attached is [module-info.class](/uploads/df948d30c53e9ce56853990500eccce4/module-info.class) file that ASM seems to be having problem with. Thanks in advance for looking into this.https://gitlab.ow2.org/asm/asm/-/issues/317792InnerClasses are lost during expansion of ASM pseudo instructions2017-12-30T16:12:13ZEvgeny MandrikovInnerClasses are lost during expansion of ASM pseudo instructions```
Original issue was reported in https://github.com/jacoco/jacoco/issues/584
Based on materials in it, I created isolated reproducer that you'll find in
attachment. Result is the same for ASM 5.2 and 6.0_BETA, older versions was
not ...```
Original issue was reported in https://github.com/jacoco/jacoco/issues/584
Based on materials in it, I created isolated reproducer that you'll find in
attachment. Result is the same for ASM 5.2 and 6.0_BETA, older versions was
not tested.
I'm not 100% sure, but similarly to comments in
#317748
following lines in ClassWriter look suspicious:
if (hasAsmInsns) {
anns = null;
ianns = null;
attrs = null;
innerClassesCount = 0; // <---
innerClasses = null; // <---
firstField = null;
lastField = null;
firstMethod = null;
lastMethod = null;
compute = MethodWriter.INSERTED_FRAMES;
hasAsmInsns = false;
new ClassReader(out.data).accept(this, ClassReader.EXPAND_FRAMES
| ClassReader.EXPAND_ASM_INSNS);
return toByteArray();
}
Regards,
Evgeny
```https://gitlab.ow2.org/asm/asm/-/issues/317789Java 8 type-use annotation on local variable in a method overriding a paramet...2024-01-26T17:01:01ZyborovikovJava 8 type-use annotation on local variable in a method overriding a parameterized one breaks ClassReader```
The following code breaks ClassReader (processing Impl.class):
abstract class Base<T> {
abstract T m();
}
class Impl extends Base<Void> {
Void m() {
@TypeUseAnnotation Object o = new Object();
return null;
...```
The following code breaks ClassReader (processing Impl.class):
abstract class Base<T> {
abstract T m();
}
class Impl extends Base<Void> {
Void m() {
@TypeUseAnnotation Object o = new Object();
return null;
}
}
@Target({ ElementType.TYPE_USE })
@interface TypeUseAnnotation {}
Running something like:
new ClassReader(Impl.class.getName()).accept(new ClassWriter(0), 0);
yields:
java.lang.ArrayIndexOutOfBoundsException: 8
at org.objectweb.asm.ClassReader.readLabel(Unknown Source)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.b(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at com.example.Test.test(Test.java:10)
this could be an issue with the bytecode produced by javac (tested on oracle
javac 1.8.0_131 and 1.8.0_152-ea):
$ javap -p -v -c Impl.class
...
class com.example.Impl extends com.example.Base<java.lang.Void>
minor version: 0
major version: 52
flags: ACC_SUPER
Constant pool:
#1 = Methodref #6.#25 // com/example/Base."<init>":()V
#2 = Class #26 // java/lang/Object
#3 = Methodref #2.#25 // java/lang/Object."<init>":()V
#4 = Methodref #5.#27 // com/example/Impl.m:()Ljava/lang/Void;
#5 = Class #28 // com/example/Impl
#6 = Class #29 // com/example/Base
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/example/Impl;
#14 = Utf8 m
#15 = Utf8 ()Ljava/lang/Void;
#16 = Utf8 o
#17 = Utf8 Ljava/lang/Object;
#18 = Utf8 RuntimeInvisibleTypeAnnotations
#19 = Utf8 Lcom/example/TypeUseAnnotation;
#20 = Utf8 ()Ljava/lang/Object;
#21 = Utf8 Signature
#22 = Utf8 Lcom/example/Base<Ljava/lang/Void;>;
#23 = Utf8 SourceFile
#24 = Utf8 Impl.java
#25 = NameAndType #7:#8 // "<init>":()V
#26 = Utf8 java/lang/Object
#27 = NameAndType #14:#15 // m:()Ljava/lang/Void;
#28 = Utf8 com/example/Impl
#29 = Utf8 com/example/Base
{
com.example.Impl();
descriptor: ()V
flags:
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method
com/example/Base."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/example/Impl;
java.lang.Void m();
descriptor: ()Ljava/lang/Void;
flags:
Code:
stack=2, locals=2, args_size=1
0: new #2 // class java/lang/Object
3: dup
4: invokespecial #3 // Method
java/lang/Object."<init>":()V
7: astore_1
8: aconst_null
9: areturn
LineNumberTable:
line 6: 0
line 7: 8
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/example/Impl;
8 2 1 o Ljava/lang/Object;
RuntimeInvisibleTypeAnnotations:
0: #19(): LOCAL_VARIABLE, {start_pc=8, length=2, index=1}
java.lang.Object m();
descriptor: ()Ljava/lang/Object;
flags: ACC_BRIDGE, ACC_SYNTHETIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokevirtual #4 // Method m:()Ljava/lang/Void;
4: areturn
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/example/Impl;
RuntimeInvisibleTypeAnnotations:
0: #19(): LOCAL_VARIABLE, {start_pc=8, length=2, index=1}
}
Signature: #22 // Lcom/example/Base<Ljava/lang/Void;>;
SourceFile: "Impl.java"
```https://gitlab.ow2.org/asm/asm/-/issues/317791ASM6 creates invalid class-files2017-12-26T09:30:15ZksriniASM6 creates invalid class-files```
After updating the JDK10 source base to use ASM6, AMS produces
bad class files, when used with nashorn.
All the details have been documented in the openjdk
issue: https://bugs.openjdk.java.net/browse/JDK-8186802
``````
After updating the JDK10 source base to use ASM6, AMS produces
bad class files, when used with nashorn.
All the details have been documented in the openjdk
issue: https://bugs.openjdk.java.net/browse/JDK-8186802
```https://gitlab.ow2.org/asm/asm/-/issues/317790Cannot checkout asm source2017-12-26T09:30:36ZgromopetrCannot checkout asm source```
I'm considering contributing a patch, but alas:
> svn checkout svn://svn.forge.objectweb.org/svnroot/asm .
svn: E170013: Unable to connect to a repository at URL
'svn://svn.forge.objectweb.org/svnroot/asm'
svn: E170001: No access a...```
I'm considering contributing a patch, but alas:
> svn checkout svn://svn.forge.objectweb.org/svnroot/asm .
svn: E170013: Unable to connect to a repository at URL
'svn://svn.forge.objectweb.org/svnroot/asm'
svn: E170001: No access allowed to this repository
svn, version 1.9.3 (r1718519)
compiled Aug 10 2017, 16:59:15 on x86_64-pc-linux-gnu
```https://gitlab.ow2.org/asm/asm/-/issues/317787MethodInsnNode.itf is not always correct2017-12-26T09:32:01ZSergey PatrikeevMethodInsnNode.itf is not always correct```
The field MethodInsnNode.itf is declared with the following comment:
public class MethodInsnNode extends AbstractInsnNode {
...
/**
* If the method's owner class if an interface.
*/
public boolean itf;
.....```
The field MethodInsnNode.itf is declared with the following comment:
public class MethodInsnNode extends AbstractInsnNode {
...
/**
* If the method's owner class if an interface.
*/
public boolean itf;
...
}
But I've discovered a case when it gives a wrong value.
Suppose we have:
public interface InterfaceWithDefault {
default void foo() {
}
}
A class written in Kotlin programming language (https://kotlinlang.org/)
class KotlinSuperInterfaceDefaultCall : InterfaceWithDefault {
fun bar() {
super.foo()
}
}
We have the following bytecode:
public final bar()V
L0
LINENUMBER 12 L0
ALOAD 0
INVOKESPECIAL InterfaceWithDefault.foo ()V
L1
LINENUMBER 13 L1
RETURN
L2
LOCALVARIABLE this LKotlinSuperInterfaceDefaultCall; L0 L2 0
MAXSTACK = 1
MAXLOCALS = 1
So as you see, the bytecode contains invokespecial instruction. JVM doesn't
prohibit it (https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-
6.html#jvms-6.5.invokespecial).
But as I see in org.objectweb.asm.tree.MethodNode#check :
if (insn instanceof MethodInsnNode) {
boolean itf = ((MethodInsnNode) insn).itf;
if (itf != (insn.opcode == Opcodes.INVOKEINTERFACE)) {
throw new RuntimeException();
}
}
The only expected instruction here is 'invokeinterface'.
```https://gitlab.ow2.org/asm/asm/-/issues/317785NPE in MethodRemapper with 'chop' stack map frames and tree API2018-02-11T12:53:24ZcushonNPE in MethodRemapper with 'chop' stack map frames and tree API```
Using ClassNode together with ClassRemapper causes an NPE. FrameNode#accept(MethodVisitor) passes null for the local array when calling visitFrame, and
MethodRemapper's implementation of visitFrame assumes the array is non-null.
==...```
Using ClassNode together with ClassRemapper causes an NPE. FrameNode#accept(MethodVisitor) passes null for the local array when calling visitFrame, and
MethodRemapper's implementation of visitFrame assumes the array is non-null.
===
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.ClassNode;
public class Test {
public static void main(String[] args) throws Exception {
ClassNode node = new ClassNode();
new ClassReader(Input.class.getName()).accept(node, 0);
node.accept(new ClassRemapper(new ClassWriter(ClassWriter.COMPUTE_MAXS), new
Remapper() {}));
}
private static final class Input {
public static int f() {
int x = 0;
for (int i = 0; i < 10; ++i) {
x++;
}
for (int i = 0; i < 10; ++i) {
x++;
}
return x;
}
}
}
===
Exception in thread "main" java.lang.NullPointerException
at
org.objectweb.asm.commons.MethodRemapper.remapEntries(MethodRemapper.java:97)
at org.objectweb.asm.commons.MethodRemapper.visitFrame(MethodRemapper.java:91)
at org.objectweb.asm.tree.FrameNode.accept(FrameNode.java:155)
at org.objectweb.asm.tree.InsnList.accept(InsnList.java:162)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:817)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:727)
at org.objectweb.asm.tree.ClassNode.accept(ClassNode.java:412)
at Test.main(Test.java:14)
```https://gitlab.ow2.org/asm/asm/-/issues/317786VerifyError when added code pushes the offset of a conditional backward jump ...2017-12-26T09:32:19ZztandresVerifyError when added code pushes the offset of a conditional backward jump below -32768```
Code reproducing the issue:
https://gist.github.com/vootelerotov/23641ee63473565cf3ef5c8fbc12a791
Also uploaded it as a Maven project.
Error:
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at
branch...```
Code reproducing the issue:
https://gist.github.com/vootelerotov/23641ee63473565cf3ef5c8fbc12a791
Also uploaded it as a Maven project.
Error:
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at
branch target 32779
Exception Details:
Location:
TestClass.test()I @32771: if_icmpeq
Reason:
Expected stackmap frame at this location.
The root cause seems to be that when a conditional backward jump is converted to
GOTO_W in MethodWriter#visitJumpInsn, a jump is added to next instruction after
the conditional backward jump. This instruction might not have a stackmap frame.
Only relevant if the frames are not re-computed.
```https://gitlab.ow2.org/asm/asm/-/issues/317784java.lang.NegativeArraySizeException when resizing jump instruction in a clas...2017-12-26T09:34:13Zlauritjava.lang.NegativeArraySizeException when resizing jump instruction in a class without frames```
With asm 5.2 attached program fails with:
Exception in thread "main" java.lang.NegativeArraySizeException
at org.objectweb.asm.Frame.merge(Frame.java:1447)
at org.objectweb.asm.CurrentFrame.execute(CurrentFrame.java:52)
at org.obj...```
With asm 5.2 attached program fails with:
Exception in thread "main" java.lang.NegativeArraySizeException
at org.objectweb.asm.Frame.merge(Frame.java:1447)
at org.objectweb.asm.CurrentFrame.execute(CurrentFrame.java:52)
at org.objectweb.asm.MethodWriter.visitInsn(MethodWriter.java:747)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1367)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1032)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:708)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:521)
at org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:1003)
at Main.main(Main.java:59)
```https://gitlab.ow2.org/asm/asm/-/issues/317776SignatureReader crashes on wildcard array element signatures2017-12-26T09:38:18ZcushonSignatureReader crashes on wildcard array element signatures```
SignatureReader crashes on arrays whose element type is a wildcard.
This isn't permitted by the grammar in JVMS8 4.7.9.1, but javac and ecj produce code that
does this.
More discussion: http://mail.openjdk.java.net/pipermail/compi...```
SignatureReader crashes on arrays whose element type is a wildcard.
This isn't permitted by the grammar in JVMS8 4.7.9.1, but javac and ecj produce code that
does this.
More discussion: http://mail.openjdk.java.net/pipermail/compiler-dev/2016-
October/010459.html
=== Test.java ===
class A<X> { class I {} }
class Test {
class B<Y> extends A<Y[]> {}
B<?>.I i;
}
===
$ javac Test.java
$ javap -v Test
...
A<?[]>.I i;
descriptor: LA$I;
flags:
Signature: #12 // LA<[*>.I;
$ java -cp asm-debug-all-5.1.jar:. org.objectweb.asm.util.Textifier Test
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of
range: 9
at java.lang.String.charAt(String.java:646)
at org.objectweb.asm.signature.SignatureReader.parseType(SignatureReader.java:206)
at org.objectweb.asm.signature.SignatureReader.acceptType(SignatureReader.java:130)
at org.objectweb.asm.util.Textifier.visitField(Textifier.java:359)
at org.objectweb.asm.util.Textifier.visitField(Textifier.java:52)
at org.objectweb.asm.util.TraceClassVisitor.visitField(TraceClassVisitor.java:195)
at org.objectweb.asm.ClassReader.readField(ClassReader.java:768)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:689)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:506)
at org.objectweb.asm.util.Textifier.main(Textifier.java:213)
```https://gitlab.ow2.org/asm/asm/-/issues/317580Data flow analyzer doesn't execute all paths in some methods with subroutines2017-12-26T09:56:15ZdmaplesdenData flow analyzer doesn't execute all paths in some methods with subroutines```
I have found that in some very unusual situations the data flow analysis
implemented in org.objectweb.asm.tree.analysis.Analyzer doesn't evaluate all
paths through the method.
I believe the problem is with how subroutines are being ...```
I have found that in some very unusual situations the data flow analysis
implemented in org.objectweb.asm.tree.analysis.Analyzer doesn't evaluate all
paths through the method.
I believe the problem is with how subroutines are being handled. The code that
deals with the JSR opcode merges the jump frame with the current frame, but the
jump instruction is not queued if the merge produces no changes.
Whilst this makes sense by itself the problem is that this means the RET
instruction (for returning from the subroutine) is not re-evaluated, meaning
that the checks that occur when the RET instruction is handled to see if the
instruction following the JSR (which is where the RET instruction returns the
control flow to) need to be re-evaluated are never performed.
This is a problem because if you have arrived at the JSR instruction with a new
frame state, even if you don't need to re-evaluate the subroutine, you do need
to re-evaluate the rest of the control flow continuing on after the return from
the subroutine.
I have a patch which appears to fix the problem for me, it basically does a
normal merge on the subsequent instruction if the subroutine is not going to be
re-evaluated (code starting at line 210).
if (insnOpcode == JSR) {
merge(jump, current, new Subroutine(j.label,
m.maxLocals, j));
// new code
if (!queued[jump]) {
// if the subroutine isn't going to be re-evaluated
// we still need to continue execution from
here as the frame state might be different
// this mimics what happens when we get the RET
instruction
// pop the value pushed by JSR
current.pop();
// check if the next instruction needs to be
re-evaluated
// we don't need to worry about merging the
results of the subroutine, because it wasn't re-evaluated!
merge(insn + 1, current, subroutine);
newControlFlowEdge(insn, insn + 1);
}
// end new code
} else {
merge(jump, current, subroutine);
}
Please note that this situation is very unusual and I have found only one or
two instances of it amongst tens of thousands of java methods.
One example I have is
org.apache.xpath.axes.FilterExprIteratorSimple.executeFilterExpr() from one
version of xalan. I will upload the exact version of xalan I am using in case
you want to test against exactly this case.
```https://gitlab.ow2.org/asm/asm/-/issues/317780IAE at CheckMethodAdapter.checkInternalName for non-Java-identifier name2017-12-26T09:35:57ZudalovIAE at CheckMethodAdapter.checkInternalName for non-Java-identifier name```
Please use the following short program to reproduce the issue:
import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter;
import org.objectweb.asm.util.CheckSignatureAdapter;...```
Please use the following short program to reproduce the issue:
import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter;
import org.objectweb.asm.util.CheckSignatureAdapter;
public class Test {
public static void main(String[] args) {
SignatureWriter sw = new SignatureWriter();
SignatureVisitor sv = new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE,
sw).visitSuperclass();
sv.visitClassType("Foo Bar"); // note the whitespace in the name
sv.visitEnd();
System.out.println(sw.toString());
}
}
The program fails with the following exception:
java.lang.IllegalArgumentException: Invalid class name (must be a fully qualified class name in internal form):
Foo Bar
at org.objectweb.asm.util.CheckMethodAdapter.checkInternalName(CheckMethodAdapter.java:1354)
at org.objectweb.asm.util.CheckMethodAdapter.checkInternalName(CheckMethodAdapter.java:1321)
at org.objectweb.asm.util.CheckSignatureAdapter.visitClassType(CheckSignatureAdapter.java:280)
at Test.main(Test.java:25)
The exception is thrown because "Foo Bar" is not a Java identifier (see Character.isJavaIdentifier* calls in
CheckMethodAdapter.checkIdentifier). However, according to JVMS 8, §4.7.9.1
(https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.9.1), this name should be
allowed:
> The grammar includes the terminal symbol Identifier to denote the name of a type, field, method, formal
parameter, local variable, or type variable, as generated by a Java compiler. Such a name must not contain
any of the ASCII characters . ; [ / < > : (that is, the characters forbidden in method names (§4.2.2) and also
colon) but may contain characters that must not appear in an identifier in the Java programming language
(JLS §3.8).
I think CheckMethodAdapter.checkIdentifier should be fixed to support not only names which are Java
identifiers, but also other names allowed by the spec.
Note that this issue causes the Kotlin (kotlinlang.org) compiler to fail on a rather simple example:
https://youtrack.jetbrains.com/issue/KT-10494
```https://gitlab.ow2.org/asm/asm/-/issues/317782OSGI import statement broken2017-12-26T09:34:58ZlostinicelandOSGI import statement broken```
The OSGi artifact uses a broken import-statement in the MANIFEST.MF.
Import-Package: org.objectweb.asm;version="[6.0_ALPHA,6.0_ALPHA]"
6.0_ALPHA is not a numeric value. OSGI uses major.minor.bugfix.qualifier and
all segments expect...```
The OSGi artifact uses a broken import-statement in the MANIFEST.MF.
Import-Package: org.objectweb.asm;version="[6.0_ALPHA,6.0_ALPHA]"
6.0_ALPHA is not a numeric value. OSGI uses major.minor.bugfix.qualifier and
all segments expect the qualifier must be of type String. The correct import
would be "[6.0.0,7.0.0)" assuming you want a upper bound to 7.0.0 (just as an
example)
```https://gitlab.ow2.org/asm/asm/-/issues/317777Infinite loop fix breaks JavaFlow continuation support2017-12-26T09:37:57ZdashorstInfinite loop fix breaks JavaFlow continuation support```
The commit below broke support for the (now rather obsolete) commons-javaflow project, or rather it
breaks the unit tests with class loading issues.
commit 2b155e17098a41a38d3819d79a7c6ec69d7a1e07
Author: ebruneton <ebruneton@271bd...```
The commit below broke support for the (now rather obsolete) commons-javaflow project, or rather it
breaks the unit tests with class loading issues.
commit 2b155e17098a41a38d3819d79a7c6ec69d7a1e07
Author: ebruneton <ebruneton@271bd773-ee82-43a6-9b2b-1890ed8ce7f9>
Date: Sat Sep 1 15:52:49 2012 +0000
Fixed bug in MethodNode (infinite loops when trying to copy a MethodNode into another several
times).
Added unit test for this case (failing without the bug fix).
diff --git a/asm/src/org/objectweb/asm/tree/MethodNode.java
b/asm/src/org/objectweb/asm/tree/MethodNode.java
index f3bbdbd..bf380cf 100644
--- a/asm/src/org/objectweb/asm/tree/MethodNode.java
+++ b/asm/src/org/objectweb/asm/tree/MethodNode.java
@@ -458,7 +458,7 @@ public class MethodNode extends MethodVisitor {
*/
protected LabelNode getLabelNode(final Label l) {
if (!(l.info instanceof LabelNode)) {
- l.info = new LabelNode(l);
+ l.info = new LabelNode();
}
return (LabelNode) l.info;
}
diff --git a/asm/test/conform/org/objectweb/asm/tree/ClassNodeUnitTest.java
b/asm/test/conform/org/objectweb/asm/tree/ClassNodeUnitTest.java
index 5754b81..988038b 100644
--- a/asm/test/conform/org/objectweb/asm/tree/ClassNodeUnitTest.java
+++ b/asm/test/conform/org/objectweb/asm/tree/ClassNodeUnitTest.java
@@ -32,6 +32,7 @@ package org.objectweb.asm.tree;
import junit.framework.TestCase;
import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
/**
@@ -138,4 +139,18 @@ public class ClassNodeUnitTest extends TestCase implements Opcodes {
MultiANewArrayInsnNode manan = new MultiANewArrayInsnNode("[[I", 2);
assertEquals(AbstractInsnNode.MULTIANEWARRAY_INSN, manan.getType());
}
+
+ public void testCloneMethod() {
+ MethodNode n = new MethodNode();
+ Label l0 = new Label();
+ Label l1 = new Label();
+ n.visitCode();
+ n.visitLabel(l0);
+ n.visitInsn(Opcodes.NOP);
+ n.visitLabel(l1);
+ n.visitEnd();
+ MethodNode n1 = new MethodNode();
+ n.accept(n1);
+ n.accept(n1);
+ }
}
The class loading issue that arises is the following stack trace:
java.lang.NoClassDefFoundError: org/apache/commons/javaflow/rewrite/Simple
at
org.apache.commons.javaflow.suite.VerificationTestCase.testSimpleSuspend(VerificationTestCase.java:18
8)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.javaflow.rewrite.Simple Undefined
label used
at
org.apache.commons.javaflow.helper.ClassTransformerClassLoader.loadClass(ClassTransformerClassLoa
der.java:113)
... 22 more
Caused by: java.lang.IllegalStateException: Undefined label used
at org.objectweb.asm.util.CheckMethodAdapter.visitMaxs(CheckMethodAdapter.java:1013)
at
org.apache.commons.javaflow.bytecode.transformation.asm.ContinuationMethodAdapter.visitMaxs(Conti
nuationMethodAdapter.java:313)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:835)
at
org.apache.commons.javaflow.bytecode.transformation.asm.ContinuationMethodAnalyzer.visitEnd(Contin
uationMethodAnalyzer.java:140)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1036)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:708)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:521)
at
org.apache.commons.javaflow.bytecode.transformation.asm.AsmClassTransformer.transform(AsmClassTr
ansformer.java:49)
at
org.apache.commons.javaflow.bytecode.transformation.asm.AsmClassTransformer.transform(AsmClassTr
ansformer.java:41)
at
org.apache.commons.javaflow.helper.ClassTransformerClassLoader.transform(ClassTransformerClassLoa
der.java:58)
at
org.apache.commons.javaflow.helper.ClassTransformerClassLoader.loadClass(ClassTransformerClassLoa
der.java:102)
... 22 more
Which is caused by the CheckMethodAdapter.visitMax(...) done in the following code:
public void visitMaxs(int maxStack, int maxLocals) {
Label endLabel = new Label();
mv.visitLabel(endLabel);
mv.visitLocalVariable("__stackRecorder", "L" + STACK_RECORDER + ";", null, startLabel, endLabel,
stackRecorderVar);
mv.visitMaxs(0, 0);
}
Reïntroducing the l parameter to the LabelNode constructor fixes these exceptions.
I have no experience in both ASM and javaflow frameworks, but try to ensure that javaflow and a recent
release of ASM work together.
You can find the code for the javaflow project here (if necessary):
https://github.com/topicusonderwijs/commons-javaflow
The method that falls flat with the exception is the following:
https://github.com/topicusonderwijs/commons-
javaflow/blob/master/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/Continu
ationMethodAdapter.java#L313
```https://gitlab.ow2.org/asm/asm/-/issues/317781Broken OSGi import statement2017-12-26T09:35:26ZlostinicelandBroken OSGi import statement```
The OSGi artifact uses a broken import-statement in the MANIFEST.MF.
Import-Package: org.objectweb.asm;version="[6.0_ALPHA,6.0_ALPHA]"
6.0_ALPHA is not a numeric value. OSGI uses major.minor.bugfix.qualifier and
all segments expect...```
The OSGi artifact uses a broken import-statement in the MANIFEST.MF.
Import-Package: org.objectweb.asm;version="[6.0_ALPHA,6.0_ALPHA]"
6.0_ALPHA is not a numeric value. OSGI uses major.minor.bugfix.qualifier and
all segments expect the qualifier must be of type String. The correct import
would be "[6.0.0,7.0.0)" assuming you want a upper bound to 7.0.0 (just as an
example)
```https://gitlab.ow2.org/asm/asm/-/issues/317778Java 8 type-use annotation breaks ClassReader in some cases2017-12-26T09:37:33ZyborovikovJava 8 type-use annotation breaks ClassReader in some cases```
The following code breaks maven-shade-plugin relocation:
```
import org.jetbrains.annotations.Nullable;
interface Foo<V> { void foo(V x); }
public abstract class FooImpl implements Foo<Iterable<Object>> {
public void foo(Itera...```
The following code breaks maven-shade-plugin relocation:
```
import org.jetbrains.annotations.Nullable;
interface Foo<V> { void foo(V x); }
public abstract class FooImpl implements Foo<Iterable<Object>> {
public void foo(Iterable<Object> result) {
if ("".equals(null)) {
@Nullable Object o = null;
o = null; // without a statement here errs at offset 65535 instead of 11
}
}
}
```
```
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-
plugin:2.4.3:shade (default) on project asm-bug: Error creating shaded jar: Error in ASM
processing class FooImpl.class: 11 -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal
org.apache.maven.plugins:maven-shade-plugin:2.4.3:shade (default) on project asm-bug:
Error creating shaded jar: Error in ASM processing class FooImpl.class
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleB
uilder.java:116)
at
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleB
uilder.java:80)
at
org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(Sin
gleThreadedBuilder.java:51)
at
org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43
)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at
org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: Error creating shaded jar:
Error in ASM processing class FooImpl.class
at org.apache.maven.plugins.shade.mojo.ShadeMojo.execute(ShadeMojo.java:540)
at
org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginMana
ger.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
... 20 more
Caused by: org.apache.maven.plugin.MojoExecutionException: Error in ASM processing
class FooImpl.class
at
org.apache.maven.plugins.shade.DefaultShader.addRemappedClass(DefaultShader.java:45
0)
at
org.apache.maven.plugins.shade.DefaultShader.shadeSingleJar(DefaultShader.java:219)
at org.apache.maven.plugins.shade.DefaultShader.shadeJars(DefaultShader.java:179)
at org.apache.maven.plugins.shade.DefaultShader.shade(DefaultShader.java:104)
at org.apache.maven.plugins.shade.mojo.ShadeMojo.execute(ShadeMojo.java:454)
... 22 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 11
at org.objectweb.asm.ClassReader.readLabel(Unknown Source)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.b(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at
org.apache.maven.plugins.shade.DefaultShader.addRemappedClass(DefaultShader.java:44
6)
... 26 more
```
```https://gitlab.ow2.org/asm/asm/-/issues/317779The Shrinking in Build Process Turns the Bytecode to Java 1.22017-12-26T09:37:12ZseamlikThe Shrinking in Build Process Turns the Bytecode to Java 1.2```
This bug was found when I was packaging Jack (Java Android Compiler Kit [1])
into Debian and I also submitted the bug to Debian's Bug Tracking System [2].
When compiling Jack, an error occured:
```
<somewhere>/android-toolchain-jac...```
This bug was found when I was packaging Jack (Java Android Compiler Kit [1])
into Debian and I also submitted the bug to Debian's Bug Tracking System [2].
When compiling Jack, an error occured:
```
<somewhere>/android-toolchain-jack/jill/src/com/android/jill/frontend/java/MethodBodyWriter.java:196:
error: type Analyzer does not take parameters
private final Analyzer<BasicValue> analyzer;
^
```
By looking at the source code [3] I found it referenced the generic type
`org.objectweb.asm.tree.analysis.Analyzer` which clearly has a type parameter,
however the compiler still complained. When I checked the file type of the
classes in `asm.jar` it gave me "compiled Java class data, version 46.0 (Java
1.2)". After I turned off the shrinking by adding `-Dproduct.noshrink=true` to
the build command as instructed in [4], Jack was compiled successfully and the
classes became Java 1.5.
I don't see anything mentioning that the shrink process would turn the Bytecode
into Java 1.2, so I am considering this a bug.
[1]: https://source.android.com/source/jack.html
[2]: https://bugs.debian.org/845606
[3]:
https://android.googlesource.com/toolchain/jack/+/ub-jack-douarn-b8/jill/src/com/android/jill/frontend/java/MethodBodyWriter.java#196
[4]: http://asm.ow2.org/doc/developer-guide.html#building
```https://gitlab.ow2.org/asm/asm/-/issues/317775Possible wrong class type parameter type annotation index2017-12-26T09:38:54ZhkueckerPossible wrong class type parameter type annotation index```
My test case class is
public class TestTypeAnnotationOnClassTypeparamWildcard1<
@TypeAnno00 T_EXT_INTERSECTION extends
@TypeAnno01 java.util.List<
@TypeAnno02 String > &
@TypeAnno03 Iterable<
@TypeAnno04 String > &
@Typ...```
My test case class is
public class TestTypeAnnotationOnClassTypeparamWildcard1<
@TypeAnno00 T_EXT_INTERSECTION extends
@TypeAnno01 java.util.List<
@TypeAnno02 String > &
@TypeAnno03 Iterable<
@TypeAnno04 String > &
@TypeAnno05 Serializable
>
{
}
I parse the class file of the java file above with ASM 5.1 AsmDomClassVisitor.
Here a part of my overriding visitTypeAnnotation method:
@Override
public AnnotationVisitor visitTypeAnnotation(
final int typeRef ,
final TypePath typePath ,
final String desc ,
final boolean visibleAtRuntime )
{
System.out.println( ( "typeRef: " + typeRef + " typePath: " + typePath + "
desc: " + desc + " visibleAtRuntime: " + visibleAtRuntime );
System.out.println( DebugUtil.intToBinaryStringWithGroup6( typeRef ) );
System.out.println( Integer.toBinaryString( ( typeRef >>> 24 ) ) );
System.out.println( "typeRef CLASS_TYPE_PARAMETER " + ( ( typeRef >>>
24 ) == TypeReference.CLASS_TYPE_PARAMETER ) );
System.out.println( "typeRef CLASS_EXTENDS " + ( ( typeRef >>>
24 ) == TypeReference.CLASS_EXTENDS ) );
System.out.println( "typeRef CLASS_TYPE_PARAMETER_BOUND " + ( ( typeRef >>>
24 ) == TypeReference.CLASS_TYPE_PARAMETER_BOUND ) );
if ( ( typeRef >>> 24 ) == TypeReference.CLASS_TYPE_PARAMETER )
{
final int typeParameterIndex = new TypeReference( typeRef
).getTypeParameterIndex();
System.out.println( "typeParameterIndex " + typeParameterIndex );
}
if ( ( typeRef >>> 24 ) == TypeReference.CLASS_TYPE_PARAMETER_BOUND )
{
final int typeParameterIndex = new TypeReference( typeRef
).getTypeParameterIndex();
System.out.println( "typeParameterIndex " + typeParameterIndex );
final int typeParameterBoundIndex = new TypeReference( typeRef
).getTypeParameterBoundIndex();
System.out.println( "typeParameterBoundIndex " + typeParameterBoundIndex );
}
Following output occurs:
typeRef: 0 typePath: null desc: LTypeAnno00; visibleAtRuntime: true
00000000 00000000 00000000 00000000
0
typeRef CLASS_TYPE_PARAMETER true
typeRef CLASS_EXTENDS false
typeRef CLASS_TYPE_PARAMETER_BOUND false
typeParameterIndex 0
typeRef: 285212928 typePath: null desc: LTypeAnno01; visibleAtRuntime: true
00010001 00000000 00000001 00000000
10001
typeRef CLASS_TYPE_PARAMETER false
typeRef CLASS_EXTENDS false
typeRef CLASS_TYPE_PARAMETER_BOUND true
typeParameterIndex 0
typeParameterBoundIndex 1
typeRef: 285212928 typePath: 0; desc: LTypeAnno02; visibleAtRuntime: true
00010001 00000000 00000001 00000000
10001
typeRef CLASS_TYPE_PARAMETER false
typeRef CLASS_EXTENDS false
typeRef CLASS_TYPE_PARAMETER_BOUND true
typeParameterIndex 0
typeParameterBoundIndex 1
typeRef: 285213184 typePath: null desc: LTypeAnno03; visibleAtRuntime: true
00010001 00000000 00000010 00000000
10001
typeRef CLASS_TYPE_PARAMETER false
typeRef CLASS_EXTENDS false
typeRef CLASS_TYPE_PARAMETER_BOUND true
typeParameterIndex 0
typeParameterBoundIndex 2
typeRef: 285213184 typePath: null desc: LTypeAnno04; visibleAtRuntime: true
00010001 00000000 00000010 00000000
10001
typeRef CLASS_TYPE_PARAMETER false
typeRef CLASS_EXTENDS false
typeRef CLASS_TYPE_PARAMETER_BOUND true
typeParameterIndex 0
typeParameterBoundIndex 2
typeRef: 285213440 typePath: null desc: LTypeAnno05; visibleAtRuntime: true
00010001 00000000 00000011 00000000
10001
typeRef CLASS_TYPE_PARAMETER false
typeRef CLASS_EXTENDS false
typeRef CLASS_TYPE_PARAMETER_BOUND true
typeParameterIndex 0
typeParameterBoundIndex 3
The typeParameterBoundIndex for TypeAnno01 starts with 1, not with 0.
Is this correct?
Thanks
Heiner
```https://gitlab.ow2.org/asm/asm/-/issues/317773Wrong typepath for array type annotations2017-12-26T09:39:59ZhkueckerWrong typepath for array type annotations```
My test class contains an string array field with type annotations:
File TestTypeAnnotationOnFieldArra.java
@NotNull
String @NotEmpty [] strArr = null;
The type annotations are self written:
File NotNull.java
package de.heiner...```
My test class contains an string array field with type annotations:
File TestTypeAnnotationOnFieldArra.java
@NotNull
String @NotEmpty [] strArr = null;
The type annotations are self written:
File NotNull.java
package de.heinerkuecker.and so on;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE_USE } )
@Inherited
@Documented
public @interface NotNull
{
}
File NotEmpty.java
package de.heinerkuecker.and so on;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE_USE } )
@Inherited
@Documented
public @interface NotEmpty
{
}
I parse the byte code of TestTypeAnnotationOnFieldArra.class with an
implementation class of
org.objectweb.asm.FieldVisitor
public final class AsmDomFieldVisitor
extends FieldVisitor
{
@Override
public AnnotationVisitor visitTypeAnnotation(
final int typeRef ,
final TypePath typePath ,
final String desc ,
final boolean visibleAtRuntime )
{
System.out.println( ( new Exception() ).getStackTrace()[ 0 ] + " typeRef: " +
typeRef + " typePath: " + typePath + " desc: " + desc + " visibleAtRuntime: " +
visibleAtRuntime );
In my console following output occurs:
de.heinerkuecker.and so
on.AsmDomFieldVisitor.visitTypeAnnotation(AsmDomFieldVisitor.java:87) typeRef:
318767104 typePath: null desc: Lde/heinerkuecker/and so
on/test_data/annotation_def/NotEmpty; visibleAtRuntime: true
de.heinerkuecker.and so
on.AsmDomFieldVisitor.visitTypeAnnotation(AsmDomFieldVisitor.java:87) typeRef:
318767104 typePath: [ desc: Lde/heinerkuecker/and so
on/test_data/annotation_def/NotNull; visibleAtRuntime: true
The typepath of the NotEmpty annotaion is null, which the entire type means and
the typepath of the NotNull is '[', which the array element type means.
This assignment of annotation to typepath is vice versa to my expectation.
Thank you for help and for the amazing asm lib.
Heiner
```https://gitlab.ow2.org/asm/asm/-/issues/317772ClassRemapper is unable to rename classes using ASM?2017-12-26T09:40:19ZvincbreakerClassRemapper is unable to rename classes using ASM?```
Hi there,
I've been trying to obfuscate my obfuscator with itself so I copyied the
builded jar file and tryed to run my obfuscator over it which gave me following
error output:
[INFO] Now processing "net.newtownia.Smoke.Obfuscation...```
Hi there,
I've been trying to obfuscate my obfuscator with itself so I copyied the
builded jar file and tryed to run my obfuscator over it which gave me following
error output:
[INFO] Now processing "net.newtownia.Smoke.Obfuscation.Flow.IfObfuscation".
[INFO] Now processing "net.newtownia.Smoke.Obfuscation.Flow.IfObfuscationAdapter".
[WARN] An error occurred while obfuscating
"net.newtownia.Smoke.Obfuscation.Flow.IfObfuscationAdapter", stacktrace:
[WARN] java.lang.RuntimeException: java.lang.ClassNotFoundException:
net.newtownia.Smoke.Obfuscation.Flow.IfObfuscation
[WARN] at org.objectweb.asm.ClassWriter.getCommonSuperClass(Unknown Source)
[WARN] at org.objectweb.asm.ClassWriter.a(Unknown Source)
[WARN] at org.objectweb.asm.Frame.a(Unknown Source)
[WARN] at org.objectweb.asm.Frame.a(Unknown Source)
[WARN] at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
[WARN] at org.objectweb.asm.MethodVisitor.visitMaxs(Unknown Source)
[WARN] at org.objectweb.asm.ClassReader.a(Unknown Source)
[WARN] at org.objectweb.asm.ClassReader.b(Unknown Source)
[WARN] at org.objectweb.asm.ClassReader.accept(Unknown Source)
[WARN] at org.objectweb.asm.ClassReader.accept(Unknown Source)
[WARN] at u.obfuscate(Smoke.java:179)
[WARN] at u.run(Smoke.java:55)
[WARN] at A.main(Main.java:29)
The obfuscator is only obfuscating class names at the moment.
```https://gitlab.ow2.org/asm/asm/-/issues/317795Source jar contains duplicated entries for every file2017-12-26T09:28:03ZBenoit DalozeSource jar contains duplicated entries for every fileThe asm-VERSION-sources.jar available on [Maven Central](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.ow2.asm%22%20AND%20a%3A%22asm%22)
from version 5.0.4 or earlier upto the latest 6.0
all contain duplicated entries in the ...The asm-VERSION-sources.jar available on [Maven Central](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.ow2.asm%22%20AND%20a%3A%22asm%22)
from version 5.0.4 or earlier upto the latest 6.0
all contain duplicated entries in the `sources.jar`.
```
$ jar tvf asm-6.0-sources.jar | sort
...
8879 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/ModuleWriter.java
8879 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/ModuleWriter.java
9092 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/commons/RemappingMethodAdapter.java
9092 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/commons/RemappingMethodAdapter.java
9135 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/xml/SAXAnnotationAdapter.java
9135 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/xml/SAXAnnotationAdapter.java
9139 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/util/TraceSignatureVisitor.java
9139 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/util/TraceSignatureVisitor.java
9540 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/commons/Method.java
9540 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/commons/Method.java
9792 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/tree/analysis/Interpreter.java
9792 Sat Sep 23 08:21:32 CEST 2017 org/objectweb/asm/tree/analysis/Interpreter.java
```
I would guess this is a problem created by the build system.
Could this be fixed?
It causes confusion for downstream tools using these jars.https://gitlab.ow2.org/asm/asm/-/issues/317796Arguments swapped in call to cattrs.put in MethodWriter2017-12-26T09:27:44ZAndrew RiceArguments swapped in call to cattrs.put in MethodWriterThe arguments `maxLocals` and `maxStack` are the wrong way round in the call to `Attribute.put` in MethodWriter.java
https://gitlab.ow2.org/asm/asm/blob/62819c139b8ac8e3012be96dfbe4ec423f425d4f/src/org/objectweb/asm/MethodWriter.java#L2...The arguments `maxLocals` and `maxStack` are the wrong way round in the call to `Attribute.put` in MethodWriter.java
https://gitlab.ow2.org/asm/asm/blob/62819c139b8ac8e3012be96dfbe4ec423f425d4f/src/org/objectweb/asm/MethodWriter.java#L2171
```java
cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
```
Definition of Attribute.put: https://gitlab.ow2.org/asm/asm/blob/62819c139b8ac8e3012be96dfbe4ec423f425d4f/src/org/objectweb/asm/Attribute.java#L207
```java
final void put(
final ClassWriter cw,
final byte[] code,
final int len,
final int maxStack,
final int maxLocals,
final ByteVector out) {
```
(I found this while evaluating a new Error Prone check for argument selection defects: http://errorprone.info/bugpattern/ArgumentSelectionDefectChecker)https://gitlab.ow2.org/asm/asm/-/issues/317797Unexpected behaviour for ClassReader#readUTF82017-12-26T09:27:22ZSam SunUnexpected behaviour for ClassReader#readUTF8Given the index to a `CONSTANT_Utf8_info` struct within the constant pool, and a `ClassReader` instance, I'm unable to read the `CONSTANT_Utf8_info` struct without using reflection to call `ClassReader#readUTF`. This is because the `read...Given the index to a `CONSTANT_Utf8_info` struct within the constant pool, and a `ClassReader` instance, I'm unable to read the `CONSTANT_Utf8_info` struct without using reflection to call `ClassReader#readUTF`. This is because the `readUTF8` actually reads a `CONSTANT_String_info` struct. Is it possible to expose a method which allows reading a `CONSTANT_Utf8_info` struct, or make `readUTF` public?https://gitlab.ow2.org/asm/asm/-/issues/317798Ability to call Type#getElementType with specific number of dimensions2018-01-13T07:40:36ZSam SunAbility to call Type#getElementType with specific number of dimensionsIt would be very useful if the API allowed you to do something like `type.getElementType(1)` to get the type representing an array which is one dimension smaller.It would be very useful if the API allowed you to do something like `type.getElementType(1)` to get the type representing an array which is one dimension smaller.https://gitlab.ow2.org/asm/asm/-/issues/317799class file format was damaged after transform some jkd 1.4 class2017-12-26T09:27:06Zrobert lighteeclass file format was damaged after transform some jkd 1.4 classi am using asm3.3 and jdk1.6 in weblogic & spring envirionment to transform class file which was compiled by JDK1.4,after transfrom,UnsupportedClassVersionError appear. i saved the transformed bytearray to filesystem,and i found that so...i am using asm3.3 and jdk1.6 in weblogic & spring envirionment to transform class file which was compiled by JDK1.4,after transfrom,UnsupportedClassVersionError appear. i saved the transformed bytearray to filesystem,and i found that some class file was damaged,
and i tested in a simple main program which without using weblogic & spring,eveything goes well,can anyone help me ?https://gitlab.ow2.org/asm/asm/-/issues/317800Resizing jump instruction adds invalid stack frame to a class without frames2017-12-26T09:26:31ZlauritResizing jump instruction adds invalid stack frame to a class without framesProbably caused by https://gitlab.ow2.org/asm/asm/commit/8648c008d91355420653a072a5146746c293b507
With class version 49 fails with array index out of bounds when reading class, with 50 there is an extra frame that isn't supposed to be th...Probably caused by https://gitlab.ow2.org/asm/asm/commit/8648c008d91355420653a072a5146746c293b507
With class version 49 fails with array index out of bounds when reading class, with 50 there is an extra frame that isn't supposed to be there. Also that extra frame can't be decoded by javap
```java
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class Main implements Opcodes {
public static void main(String... args) {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
cw.visit(49, ACC_PUBLIC + ACC_SUPER, "Test", null, "java/lang/Object", null);
// cw.visit(50, ACC_PUBLIC + ACC_SUPER, "Test", null, "java/lang/Object", null);
{
fv = cw.visitField(0, "b", "Z", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(0, "a", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "Test", "b", "Z");
Label l1 = new Label();
mv.visitJumpInsn(IFEQ, l1);
for (int i = 0; i < 40000; i++) {
mv.visitInsn(NOP);
}
mv.visitLabel(l1);
mv.visitInsn(RETURN);
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitLocalVariable("this", "LTest;", null, l0, l3, 0);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
cw.visitEnd();
byte[] bytes = cw.toByteArray();
ClassReader cr = new ClassReader(bytes);
ClassVisitor cv = new ClassVisitor(ASM5) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(ASM5) {
@Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
throw new IllegalStateException("no frames expected");
}
};
}
};
cr.accept(cv, 0);
}
}
```https://gitlab.ow2.org/asm/asm/-/issues/317801Incorrect CONSTANT_Class format when writing frame types. Fails to pass Java ...2018-03-17T15:27:29ZVincent TangIncorrect CONSTANT_Class format when writing frame types. Fails to pass Java 9 validation.In ```ClassWriter#writeFrameTypes```, ```ClassWriter#newClass``` is called.
The method should normally take the internal name of the class, e.g. ```java/lang/Object```.
However, ```#writeFrameTypes``` prepends ```L``` and appends ```;...In ```ClassWriter#writeFrameTypes```, ```ClassWriter#newClass``` is called.
The method should normally take the internal name of the class, e.g. ```java/lang/Object```.
However, ```#writeFrameTypes``` prepends ```L``` and appends ```;```, passing the descriptor instead. This is inconsistent with the class file format.
In Java 8 virtual machines (and below), this wasn't a problem because the VM did not strictly validate the format of a Class constant. However, Java 9 virtual machines do impose this restriction, resulting in a ClassFormatError, such as the following:
```
Error: LinkageError occurred while loading main class Test
java.lang.ClassFormatError: Illegal class name "Ljava/lang/Object;" in class file Test
```https://gitlab.ow2.org/asm/asm/-/issues/317802MethodRemapper.visitInvokeDynamicInsn mutates source bsmArgs2018-09-24T18:01:58ZPlayer .MethodRemapper.visitInvokeDynamicInsn mutates source bsmArgsThe implementation replaces entries in bsmArgs with mapped values without copying bsmArgs, thus replacing them in the original representation as well. This alters the ClassNode supplied to ClassRemapper, although presumably that shouldn'...The implementation replaces entries in bsmArgs with mapped values without copying bsmArgs, thus replacing them in the original representation as well. This alters the ClassNode supplied to ClassRemapper, although presumably that shouldn't happen.https://gitlab.ow2.org/asm/asm/-/issues/3178036.0 not in maven repository2017-12-26T09:25:39Zpdeva6.0 not in maven repositoryneither maven central nor repository.ow2.org seem to contain v6.0.
Only 6.0-beta is available in bothneither maven central nor repository.ow2.org seem to contain v6.0.
Only 6.0-beta is available in bothhttps://gitlab.ow2.org/asm/asm/-/issues/317560Method Remapping: InvokeDynamicInsn#name2018-04-15T13:14:15ZcalebMethod Remapping: InvokeDynamicInsn#name```
I'm currently writing an obfuscator supporting the java 8 language level (lambdas, default interfaces etc).
At the moment I'm focusing on method name obfuscation.
Here is the transformer along with the rest of the project
https://gi...```
I'm currently writing an obfuscator supporting the java 8 language level (lambdas, default interfaces etc).
At the moment I'm focusing on method name obfuscation.
Here is the transformer along with the rest of the project
https://github.com/RevTek/Revtek-ASM-Obfuscator/blob/master/com/revtek/rasmo/obfuscate/ScrambleMethods.java
Its entirely possible I'm completely mistaken and just haven't done everything properly.
Here is an example of where the instructions weren't transformed.
Source: https://gist.github.com/RevTek/8293ebbef263eb606d5f
Obfuscated Source: https://gist.github.com/RevTek/8624a686bab369bc56a3
Obfuscated Bytecode: https://gist.github.com/RevTek/74d1ea05739d4c879c7b#file-gistfile1-txt-L54
Obfuscated DangerousTask class
https://gist.github.com/RevTek/eb89dd460c60793bdf92
As you can see, other calls to the DangerousTask class are correctly transformed, except the InvokeDynamicInsn#name, it is
still referred to as "execute", it should be "ce"
I apologize for the sloppy layout of this post, its difficult to make it neat when there are a lot of resources needed to
show the problem.
```Remi ForaxRemi Foraxhttps://gitlab.ow2.org/asm/asm/-/issues/317531Invalid lambda deserialization error after relocation of packages2018-05-19T16:08:14ZzarzykInvalid lambda deserialization error after relocation of packages```
Hi,
I'm having an issue with serializing & deserializing lambdas that were processed by asm: "Invalid lambda deserialization"
My environment:
I'm using java 8, version :
java version "1.8.0_05"
Java(TM) SE Runtime Environment (buil...```
Hi,
I'm having an issue with serializing & deserializing lambdas that were processed by asm: "Invalid lambda deserialization"
My environment:
I'm using java 8, version :
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
I'm using shadow plugin for gradle that uses asm for relocating packages and references in jars and/or class files.
I'm using the official version 0.8 from the link:
https://github.com/johnrengelman/shadow/tree/0.8
This version uses asm in version 3, but I overrode the asm dependency and set it to the freshest on Maven, which is 5.0.3:
org.ow2.asm:asm:5.0.3, org.ow2.asm:asm-commons:5.0
I created a sample project to easily reproduce the problem:
https://github.com/kzarzycki/asm-lambda-deserialization-error-test
When I run my test, I get an exception:
Exception in thread "main" java.io.IOException: unexpected exception type
at java.io.ObjectStreamClass.throwMiscException(ObjectStreamClass.java:1538)
at java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1110)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1810)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at AsmTest.deserialize(AsmTest.java:36)
at AsmTest.main(AsmTest.java:21)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at java.lang.invoke.SerializedLambda.readResolve(SerializedLambda.java:230)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1104)
... 5 more
Caused by: java.lang.IllegalArgumentException: Invalid lambda deserialization
at AsmTest.$deserializeLambda$(AsmTest.java:11)
... 15 more
I'll be grateful for your help with this issue!
```Remi ForaxRemi Foraxhttps://gitlab.ow2.org/asm/asm/-/issues/317783Give an error message when the byte code version is too new for ClassReader2018-02-27T07:55:31ZmiikkaGive an error message when the byte code version is too new for ClassReader```
If you try to initialize a ClassReader with some bytecode whose version is not supported, you get an
IllegalArgumentException without any message. It'd great if the exception would have a human-readable
explanation of the problem, ...```
If you try to initialize a ClassReader with some bytecode whose version is not supported, you get an
IllegalArgumentException without any message. It'd great if the exception would have a human-readable
explanation of the problem, maybe something along the lines of "Bytecode version is 53; the latest version
supported is 52".
```https://gitlab.ow2.org/asm/asm/-/issues/317627Separate labels for control-flow and stack-map references2018-06-16T14:21:37ZmadsagerSeparate labels for control-flow and stack-map references```
When creating a simple instrumentation pass I accidentally put code between a label
and the NEW bytecode that follows it. That led to the following error message from
the Java VM verifier:
java.lang.ClassFormatError: StackMapTable...```
When creating a simple instrumentation pass I accidentally put code between a label
and the NEW bytecode that follows it. That led to the following error message from
the Java VM verifier:
java.lang.ClassFormatError: StackMapTable format error: bad offset for
Uninitialized in method <method name>
It took me some time to figure out what that meant.
The problem for my instrumentation is that the labels used to indicate stack-map
Uninitialized references to a NEW instruction are not separate from labels used for
control flow. Therefore, when I insert code after a label used for control-flow (in
my case a default case in a switch) I have to be careful that this doesn't separate
a NEW bytecode from the label used to identify it.
control-flow label:
NEW
->
control-flow label:
ldc <num>
invokestatic <method>
NEW
If new labels were always created instead of using existing control-flow labels to
reference NEW bytecodes in stack map entries I wouldn't have run into this problem.
My instrumentation would have inserted code between the control-flow label and the
NEW bytecode label.
control-flow label:
new label:
NEW
->
control-flow label:
ldc <num>
invokestatic <method>
new label:
NEW
Such a separation between labels used for control-flow and labels used to identify
NEW bytecodes for stack maps seems useful.
```https://gitlab.ow2.org/asm/asm/-/issues/317617Invert order in which visitTryCatchBlock adds to the exception table2020-07-04T18:25:42ZraphwInvert order in which visitTryCatchBlock adds to the exception table```
When calling visitTryCatchBlock, it is currently implicit that the visited
handler is added to the bottom of the method's exception table. At the same
time, it is required that a visitTryCatchBlock method is invoked before
visiting t...```
When calling visitTryCatchBlock, it is currently implicit that the visited
handler is added to the bottom of the method's exception table. At the same
time, it is required that a visitTryCatchBlock method is invoked before
visiting the label that starts the handler. This makes a common ASM use-case
difficult to solve:
When using ASM to wrap a method or parts of a method within a try-catch-block,
any surrounding handler is always triggered first and can cause unexpected
side-effects such as this user probably encountered:
http://stackoverflow.com/questions/23491902/adding-try-catch-block-in-bytecode-through-asm
I think that it would be more intuitive if a visitedTryCatchBlock would be
added to the top of the exception handler table. This would allow to
dynamically create nested handlers. Today, these nested handlers need to be
known at the beginning of the method because the deepest handler must be called
first to end at the top of the exception table.
Consider a scenario where two method visitors add an exception handler entry
upon discovering a method foo:
try {
try {
foo();
} finally {
instrumentation1();
}
} finally {
instrumentation2();
}
When chaining to visitors the first visitor would add an exception table entry
and a label, call the super method and then add the completion label and
handler label as well as logic. The nested method visitor would do the same but
its handler would never be triggered as the handler comes at second place in
the generated exception table.
Inverting the order entries are added to the table would solve this problem and
I think it would also be more intuitive. (This could be achieved
backwards-compatible by adding a new API version to Opcodes and make the
behavior dependant on this version.)
```Eric BrunetonEric Brunetonhttps://gitlab.ow2.org/asm/asm/-/issues/317609Enhance ClassWriter to take a class loader for use with getCommonSuperClass2018-06-16T14:32:51ZnmccloudEnhance ClassWriter to take a class loader for use with getCommonSuperClass```
Would it be possible to add another constructor to
org.objectweb.asm.ClassWriter to take a ClassLoader that will be used with
getCommonSuperClass. This will eliminate the need to extend this class by
the end-developer. Both Clas...```
Would it be possible to add another constructor to
org.objectweb.asm.ClassWriter to take a ClassLoader that will be used with
getCommonSuperClass. This will eliminate the need to extend this class by
the end-developer. Both ClassWriter(ClassReader, int, ClassLoader) and
ClassWriter(int, ClassLoader) could be created easily.
Thanks,
Ken
```https://gitlab.ow2.org/asm/asm/-/issues/317585Indicate whether a label is used only for debugging in the tree API2018-06-16T13:55:52ZguichazIndicate whether a label is used only for debugging in the tree API```
ASM knows when a label is just for debugging (line numbers) or not (control
flow):
Label.java:
/**
* Indicates if this label is only used for debug attributes. Such a label
* is not the start of a basic block, the ta...```
ASM knows when a label is just for debugging (line numbers) or not (control
flow):
Label.java:
/**
* Indicates if this label is only used for debug attributes. Such a label
* is not the start of a basic block, the target of a jump instruction, or
* an exception handler. It can be safely ignored in control flow graph
* analysis algorithms (for optimization purposes).
*/
static final int DEBUG = 1;
It would be useful to have this information exported in the tree API.
The only workaround I found is to search for a label in all the non-debugging
label references I found: JumpInsnNode.label, TryCatchBlockNode.
{start,end,handler}, ... That's obviously unwieldy.
I assume that finding a LineNumberNode.start pointing at a label is not
sufficient to guarantee that said label is used only for debugging.
```https://gitlab.ow2.org/asm/asm/-/issues/317546Add more SKIP_XXX in ClassReader2018-06-16T13:50:41ZsubchenAdd more SKIP_XXX in ClassReader```
Following flags are useful to quickly scan a class.
* SKIP_FIELDS_AND_METHODS
Skips all fields and methods when we only get the class information (such
as annotations, super class, interfaces, ...)
* SKIP_CODE_INST
It is...```
Following flags are useful to quickly scan a class.
* SKIP_FIELDS_AND_METHODS
Skips all fields and methods when we only get the class information (such
as annotations, super class, interfaces, ...)
* SKIP_CODE_INST
It is NOT same with SKIP_CODE.
SKIP_CODE will skip the code and code attributes. But if we want to get
the attributes of code (such as LocalVariableTable for parameter name), we
have to parse all code instructions. I think we can only skip to code
instructions parsing and go to code attributes.
```https://gitlab.ow2.org/asm/asm/-/issues/316686Enhance ClassVisitor to support multiple chain forwarding2018-04-15T13:08:04ZcvdenzenEnhance ClassVisitor to support multiple chain forwarding```
As described in asm4-guide.pdf, chapter "2.2.7 Transformation chains" it is
possible to forward calls to several ClassVisitors.
This mechanism can be quite easily implemented (with full downward
compatibility) in ClassVisitor.
The ...```
As described in asm4-guide.pdf, chapter "2.2.7 Transformation chains" it is
possible to forward calls to several ClassVisitors.
This mechanism can be quite easily implemented (with full downward
compatibility) in ClassVisitor.
The public API could be extended by a constructor that accepts a ClassVisitor[]
argument.
This argument can be stored in a (preferably private) field (named e.g. cvs).
The original constructor(s) with a ClassVisitor argument, should store its
argument in the "old" cv field (only for backward compatibility) AND as the
first item in the cvs array.
All methods should then use the cvs array to forward calls.
The use of a protected instead of a private cv is not very clear to me. I would
prefer to call the super method over using the protected field to invoke the
(same) method. If I look at the code examples in chapter "3.2.3 Transforming
methods", the use of "mv1=super.visitMethod(..." would be better (automatic
check for null of cv) than the proposed "mv1=cv.visitMethod(...". But if I am
wrong, please try to explain it to me!
If you want me to upload an enhanced ClassVisitor, let me know.
```https://gitlab.ow2.org/asm/asm/-/issues/316577Interpreter needs to be able to distinguish parameters2018-06-16T13:44:07ZkohsukeInterpreter needs to be able to distinguish parameters```
SourceValue currently does not remember whether it came from a paramter, but
I'd like to write code that does something different for parameters.
This requires a change in the Analyzer class so that the interpreter gets the
contex...```
SourceValue currently does not remember whether it came from a paramter, but
I'd like to write code that does something different for parameters.
This requires a change in the Analyzer class so that the interpreter gets the
contextual information that the analyzer is trying to create a value for the
parameter value.
This is the current code:
if ((m.access & ACC_STATIC) == 0) {
Type ctype = Type.getObjectType(owner);
current.setLocal(local++, interpreter.newValue(ctype));
}
for (int i = 0; i < args.length; ++i) {
current.setLocal(local++, interpreter.newValue(args[i]));
if (args[i].getSize() == 2) {
current.setLocal(local++, interpreter.newValue(null));
}
}
Possible change:
if ((m.access & ACC_STATIC) == 0) {
Type ctype = Type.getObjectType(owner);
current.setLocal(local++, interpreter.newThisValue(ctype));
}
for (int i = 0; i < args.length; ++i) {
current.setLocal(local++,
interpreter.newParameterValue(i,args[i]));
if (args[i].getSize() == 2) {
current.setLocal(local++, interpreter.newValue(null));
}
}
```https://gitlab.ow2.org/asm/asm/-/issues/317568NPE in MethodWriter.visitMaxs2017-12-26T09:58:44ZjfdeniseNPE in MethodWriter.visitMaxs```
I have isolated and attached a simplified test case that reveals the NPE. I am running ASM 5.0.3
I am removing the instructions of an exception handler as well as the associated TryCatchBlockNode
instance.
This does work except w...```
I have isolated and attached a simplified test case that reveals the NPE. I am running ASM 5.0.3
I am removing the instructions of an exception handler as well as the associated TryCatchBlockNode
instance.
This does work except when a method is of the form of the NPETestCase.fails method. In this case I am
running into the following NPE:
Exception in thread "main" java.lang.NullPointerException
at jdk.internal.org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1570)
at jdk.internal.org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:864)
at jdk.internal.org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:756)
at jdk.internal.org.objectweb.asm.tree.ClassNode.accept(ClassNode.java:441)
at asm_npe1.TestNPE.main(TestNPE.java:50)
To run the test case. Open the project in netbeans and run it. If no netbeans, build the classes, run the
java class asm_npe1.TestNPE passing it the path to where the class asm_npe1.NPETestCase.class has been
generated.
```https://gitlab.ow2.org/asm/asm/-/issues/317610Error when computing stack map frames2017-12-26T09:49:27ZraphwError when computing stack map frames```
I am trying to instrument the byte code of
org.hsqldb.jdbc.JDBCStatement#executeBatch(int[]) method and I use ASM to
recompute the frames and the stack size for me. ASM does unfortunately not
compute the correct frames and a verifier...```
I am trying to instrument the byte code of
org.hsqldb.jdbc.JDBCStatement#executeBatch(int[]) method and I use ASM to
recompute the frames and the stack size for me. ASM does unfortunately not
compute the correct frames and a verifier error is thrown
I broke down the problem to adding an additional variable of type int to the
method. To do so, I am manually incresing the index of all variables by 1 if an
offset does not match that of an argument. As an example, this means that the
offset for "this" remains 0 but the offset for 1 is mapped to 2 etc. This works
for most methods.
I can reproduce very similar behavior by recompiling
org.hsqldb.jdbc.JDBCStatement#executeBatch(int[]) with an additional variable
int value = 0;
at the beginning of the method.
I attached byte code output for:
1. The original byte code that is fed to a ClassReader
2. The actual outcome that is produced by a ClassWriter when adding the
statement "int value = 0" to the beginning of the method and remapping all the
offsets.
3. The expected outcome as produced by javac when adding this manually.
If you diff (2) and (3) you can see some minor, insignificant differences
caused by the way the byte code is generated. The root cause is the stack map
frame in line 76 of (2) compared to line 73 of (3). ASM computes the stack map
frame to be
FRAME APPEND [org/hsqldb/navigator/RowSetNavigator T I]
where javac adds
FRAME APPEND [org/hsqldb/navigator/RowSetNavigator [I I]
```https://gitlab.ow2.org/asm/asm/-/issues/317793AnalyzerAdapter calculates wrong type for AALOAD in case of null2018-02-18T09:39:08ZEvgeny MandrikovAnalyzerAdapter calculates wrong type for AALOAD in case of null```
Original issue was reported in
https://groups.google.com/d/msg/jacoco/UC5rXh6CFAA/XYfrBnXZBwAJ
where you can also find steps of our analysis of the problem, below is
result of this analysis, credits to Marc Hoffmann for wording:
...```
Original issue was reported in
https://groups.google.com/d/msg/jacoco/UC5rXh6CFAA/XYfrBnXZBwAJ
where you can also find steps of our analysis of the problem, below is
result of this analysis, credits to Marc Hoffmann for wording:
According to JVMS Chapter "4.10.1.9 Type Checking Instructions, AALOAD",
the resulting type on the operand stack is
1) the component type if the input type is an array
2) or null if the input type is null
This is how the JVM verifier is implemented -- even if the latter will
always lead to a NPE at runtime.
AnalyzerAdapter handles the second case wrongly.
STEPS TO REPRODUCE
1) Visit frame with operand stack [null, int]
2) Visit AALOAD
EXPECTED BEHAVIOR
Operand Stack is [null]
ACTUAL BEHAVIOR
Operand Stack is ["java/lang/Object"]
DETAILED ANALYSIS
Ome might think this situation can be easily produces by the following
snippet:
Object[] array = null;
Object element = array[0];
// some control structure enforcing a frame here
Java compilers (e.g. JDK or ECJ) insert a frame with local variables of
type
["[Ljava/lang/Object;", "java/lang/Object"]
If the same class files has been written by ASM with the COMPUTE_FRAME flag
ASM assumes "null" for the variable, so the frame is
[null, null]
Both frame veriants pass the JVM's bytecode verifier.
If AnalyzerAdapter is used to track the frame status for the first version
the correct frame types are calculated, but for the second version
[null, "java/lang/Object"]
is calculated which fails the JVM's verifier if inserted like this. A
typical error message is:
java.lang.VerifyError: Instruction type does not match stack map
Exception Details:
Location:
org/jacoco/dev/bytecode/AALOADnullTest$Target.run()V @39: aload_1
Reason:
Type 'java/lang/Object' (current frame, locals[3]) is not
assignable to null (stack map, locals[3])
Current Frame:
bci: @39
flags: { }
locals: { 'org/jacoco/dev/bytecode/AALOADnullTest$Target', '[Z',
null, 'java/lang/Object' }
stack: { }
Stackmap Frame:
bci: @39
flags: { }
locals: { 'org/jacoco/dev/bytecode/AALOADnullTest$Target', '[Z',
null, null }
stack: { }
We think that AnalyzerAdapter can be fixed by replacing
case Opcodes.AALOAD:
pop(1);
t1 = pop();
if (t1 instanceof String) {
pushDesc(((String) t1).substring(1));
} else {
push("java/lang/Object");
}
with
case Opcodes.AALOAD:
pop(1);
t1 = pop();
if (t1 instanceof String) {
pushDesc(((String) t1).substring(1));
} else {
push(Opcodes.NULL);
}
```https://gitlab.ow2.org/asm/asm/-/issues/317559"Incompatible InnerClasses attribute" error in IBM J9 VM2017-12-26T09:59:46Zztandres"Incompatible InnerClasses attribute" error in IBM J9 VM```
ASM generates unexpected bytecode get's the following exception in some certain
cases on IBM JVM:
Caused by: java.lang.IncompatibleClassChangeError: incompatible InnerClasses
attribute between "org.zeroturnaround.Erroneous$MyInner" a...```
ASM generates unexpected bytecode get's the following exception in some certain
cases on IBM JVM:
Caused by: java.lang.IncompatibleClassChangeError: incompatible InnerClasses
attribute between "org.zeroturnaround.Erroneous$MyInner" and
"org.zeroturnaround.Erroneous"
I have seen this error before and also found a jenkins bug caused by it:
https://issues.jenkins-ci.org/browse/JENKINS-22525
The cause seems to be that in some cases the compiled byte code has 2 class
references to the same class. In the original bytecode the first reference is
used, but after ASM parses the class both references are used and this causes
some trouble for IBM JVM.
Based on that I managed to make a reproduction application. When you look at
the bytecode before and after the transformation you can see the difference.
One fix I found would be to change
ClassWriter
private Item get(final Item key) {
Item i = items[key.hashCode % items.length];
Item best = null;
while (i != null) {
if (i.type == key.type && key.isEqualTo(i)) {
if (best == null) {
best = i;
} else if (best.index > i.index) {
best = i;
}
}
i = i.next;
}
return best;
}
```https://gitlab.ow2.org/asm/asm/-/issues/317604Bug in AdviceAdapter.visitFieldInsn()2017-12-26T09:50:57ZtraskBug in AdviceAdapter.visitFieldInsn()```
Hi, I just wanted to report this issue I ran into:
Existing code:
case PUTFIELD:
popValue();
if (longOrDouble) {
popValue();
popValue();
}
break;
Should be:
case PUT...```
Hi, I just wanted to report this issue I ran into:
Existing code:
case PUTFIELD:
popValue();
if (longOrDouble) {
popValue();
popValue();
}
break;
Should be:
case PUTFIELD:
popValue();
popValue();
if (longOrDouble) {
popValue();
}
break;
Thanks,
Trask
```https://gitlab.ow2.org/asm/asm/-/issues/317749ClassCheckAdapter should discover invocation of default method from pre-Java ...2017-12-26T09:42:48ZraphwClassCheckAdapter should discover invocation of default method from pre-Java 8 class file```
Currently, the CheckClassAdapter does not recognize if a INVOKESPECIAL method
is invoked on an interface (last argument is true). This is not legal prior to
Java 8 where currently a verifer error over an illegal constant pool entry i...```
Currently, the CheckClassAdapter does not recognize if a INVOKESPECIAL method
is invoked on an interface (last argument is true). This is not legal prior to
Java 8 where currently a verifer error over an illegal constant pool entry is
the result.
```https://gitlab.ow2.org/asm/asm/-/issues/317788Parameter annotations reported incorrectly for local class constructor2018-01-20T16:19:56ZgromopetrParameter annotations reported incorrectly for local class constructor```
class NotNullBug {
public void foo(String foo, final Object bar) {
class Test {
private Test(@NotNull String test) {
System.out.println(bar);
}
}
new Test(foo);
...```
class NotNullBug {
public void foo(String foo, final Object bar) {
class Test {
private Test(@NotNull String test) {
System.out.println(bar);
}
}
new Test(foo);
}
}
Test constructor has 3 parameters in bytecode: NotNullBug outer, String test,
Object bar. The first and the third one are synthetic.
But ClassReader#readParameterAnnotations assumes that all synthetic parameters go
first, and so reports that @NotNull is on the third parameter (Object bar) which
is incorrect.
```https://gitlab.ow2.org/asm/asm/-/issues/317586VerifyError caused by LocalVariablesSorter2018-02-24T09:42:16ZjemrVerifyError caused by LocalVariablesSorter```
The LocalVariablesSorter will sometimes produce incorrect frames causing verification error.
The following method, when compiled with the eclipse compiler, will cause VerifyError, if run through the
LocalVariablesSorter:
void sa...```
The LocalVariablesSorter will sometimes produce incorrect frames causing verification error.
The following method, when compiled with the eclipse compiler, will cause VerifyError, if run through the
LocalVariablesSorter:
void sample() throws Exception {
try (BufferedReader reader = new BufferedReader(new StringReader("1\n2\n3\n4\n"))) {
String line;
while ((line = reader.readLine()) != null) {
int columnidx = 0;
Integer.parseInt(line);
}
}
}
the above with "Bad local variable type", if commenting out the parseInt line, then with: "Inconsistent stackmap frames"
It seems the "changed" flag in the LocalVariablesSorter isn't set, even though something is remapped?
See attached zip for sample (includes .class files as compiled with eclipse compiler).
```https://gitlab.ow2.org/asm/asm/-/issues/317615Type annotations cause ArrayIndexOutOfBoundsException2017-12-26T09:49:05ZtomvdbType annotations cause ArrayIndexOutOfBoundsException```
When ClassReader reads a class file containing type annotations, it fails with the following
exception:
java.lang.ArrayIndexOutOfBoundsException: 15
at org.springframework.asm.ClassReader.readLabel(ClassReader.java:2185)
at org.s...```
When ClassReader reads a class file containing type annotations, it fails with the following
exception:
java.lang.ArrayIndexOutOfBoundsException: 15
at org.springframework.asm.ClassReader.readLabel(ClassReader.java:2185)
at org.springframework.asm.ClassReader.readTypeAnnotations(ClassReader.java:1614)
....
I've been able to put together a tiny maven project that reproduces the problem (see attachment).
All you need to do is run "mvn test".
The problem occurs in ASM 5.0.4 and 5.1.
I've discovered it while using Spring, which incorporates ASM. I've submitted a ticket at Spring
(https://jira.spring.io/browse/SPR-14089), giving more details about the source code and my
findings in the attached project.
Since Spring simply copies the ASM code, I think the best solution is to fix the problem in ASM
itself.
Regards,
Tom
```https://gitlab.ow2.org/asm/asm/-/issues/317555NPE in MethodWriter.resizeInstructions()2017-12-26T10:00:47ZmarchofNPE in MethodWriter.resizeInstructions()```
ASM Version: 5.0.1
While working on a reproducer for issue 317551 I came across the following NPE
while creating a large method:
Exception in thread "main" java.lang.NullPointerException
at org.objectweb.asm.MethodWriter.resizeIns...```
ASM Version: 5.0.1
While working on a reproducer for issue 317551 I came across the following NPE
while creating a large method:
Exception in thread "main" java.lang.NullPointerException
at org.objectweb.asm.MethodWriter.resizeInstructions(MethodWriter.java:2709)
at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1407)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1554)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1017)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:693)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:506)
at org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:995)
at LargeMethodNPE.main(LargeMethodNPE.java:18)
Please find the reproducer attached.
Maybe I made a mistake using the visitor APIs, but a smaller version of the
same class (less NOP instructions) can be built and also loads into the JVM.
```https://gitlab.ow2.org/asm/asm/-/issues/317606Frequent use of StringBuffer instead of StringBuilder is hurting performance2017-12-26T09:50:37ZsteffenyountFrequent use of StringBuffer instead of StringBuilder is hurting performance```
While profiling a project recently I found that a significant amount of the total load time was being
wasted in the ASM libraries on the synchronized append() calls of the StringBuffer class.
This is totally unnecessary! The java s...```
While profiling a project recently I found that a significant amount of the total load time was being
wasted in the ASM libraries on the synchronized append() calls of the StringBuffer class.
This is totally unnecessary! The java standard StringBuilder class provides a compatible interface
and its append() calls are not synchronized.
I've attached a patch file to this bug which replaces the usage of StringBuffer with StringBuilder.
I believe the patch will not cause any significant compatibility issues since the only public
interfaces it touched were the following:
./asm/examples/attributes/src/Attributes.java: public void textify(StringBuilder buf, Map<Label,
String> labelNames) {
./asm/src/org/objectweb/asm/util/Printer.java: public static void appendString(final StringBuilder
buf, final String s) {
./asm/test/conform/org/objectweb/asm/attrs/CodeComment.java: public void asmify(final
StringBuilder buf, final String varName,
./asm/test/conform/org/objectweb/asm/attrs/CodeComment.java: public void textify(final
StringBuilder buf,
./asm/test/conform/org/objectweb/asm/attrs/Comment.java: public void asmify(final
StringBuilder buf, final String varName,
./asm/test/conform/org/objectweb/asm/attrs/Comment.java: public void textify(final
StringBuilder buf,
./asmdex/src/org/ow2/asmdex/util/TextLeaf.java: public TextLeaf(StringBuilder text) {
./eclipse/plugin/src/de/loskutov/bco/views/HelpUtils.java: public static StringBuilder
getOpcodeHelpFor(int opcode) {
```https://gitlab.ow2.org/asm/asm/-/issues/317774Test bug: new ClassReader("java.lang.Object") throws IOException("Class not f...2017-12-26T09:39:29ZhamlinTest bug: new ClassReader("java.lang.Object") throws IOException("Class not found") in jdk-9```
bug description:
IOException("Class not found") is thrown in test, the bug is in test code,
it's due to jdk-9 changes, buggy code:
1. org.objectweb.asm.ClassReaderUnitTest.java, line 81:
new ClassReader(Object.class.getName())
2....```
bug description:
IOException("Class not found") is thrown in test, the bug is in test code,
it's due to jdk-9 changes, buggy code:
1. org.objectweb.asm.ClassReaderUnitTest.java, line 81:
new ClassReader(Object.class.getName())
2. org.objectweb.asm.util.CheckClassAdapterUnitTest.java, line 469:
new ClassReader("java.lang.Object")
root cause:
some asm test calls code like 'new ClassReader("java.lang.Object")', which
will finally call code like
'ClassLoader.getSystemResourceAsStream("java/lang/Object.class")', but in
jdk-9 "Resources in a named module are private to that module.", so
getSystemResourceAsStream will return null, finally it will throw
IOException("Class not found").
```https://gitlab.ow2.org/asm/asm/-/issues/317558Stack frame tag - wrong specification2017-12-26T10:00:33ZhenStack frame tag - wrong specification```
In class Reader under method readFrame
private int readFrame(int stackMap, boolean zip, boolean unzip,
Context frame)
{
..
..
..
if (zip)
{
tag = b[stackMap++] & 0xFF;
} else {
tag = MethodWri...```
In class Reader under method readFrame
private int readFrame(int stackMap, boolean zip, boolean unzip,
Context frame)
{
..
..
..
if (zip)
{
tag = b[stackMap++] & 0xFF;
} else {
tag = MethodWriter.FULL_FRAME;
frame.offset = -1;
}
..
..
}
Why are you assuming that if zip var is true then the frame tag is FULL_FRAME
?
The zip flag is being determined according to the following code located under
the method called readCode:
private void readCode(final MethodVisitor mv, final Context context, int u)
{
..
..
else if (FRAMES && "StackMap".equals(attrName)) {
if ((context.flags & SKIP_FRAMES) == 0) {
zip = false;
stackMap = u + 10;
stackMapSize = readInt(u + 4);
frameCount = readUnsignedShort(u + 8);
}
..
..
}
Running a degenerate method visitor on the attached class causing to the
following Exception:
java.lang.ArrayIndexOutOfBoundsException: 3
at org.objectweb.asm.ClassReader.readFrameType(ClassReader.java:2142)
at org.objectweb.asm.ClassReader.readFrame(Unknown Source)
at org.objectweb.asm.ClassReader.readCode(Unknown Source)
at org.objectweb.asm.ClassReader.readMethod(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
There is no full frame in the method StackMap (Output using javap):
StackMap: length = 0x5
00 03 18 07 07
You can see that the attribute_length is 3 and all the entries are less then
63, which means the frames should be tagged as same_frame
Attached is the relevant class
Thanks,
Hen
```https://gitlab.ow2.org/asm/asm/-/issues/317748Class after instrumenting loses first BootstrapMethods entry2018-01-20T08:18:05ZztandresClass after instrumenting loses first BootstrapMethods entry```
Got the following error on loading the processed class:
Fails with Caused by: java.lang.ClassFormatError: Short length on
BootstrapMethods in class file org/zeroturnaround/Erroneous
I think it happens when MethodWriter#resizeInstruc...```
Got the following error on loading the processed class:
Fails with Caused by: java.lang.ClassFormatError: Short length on
BootstrapMethods in class file org/zeroturnaround/Erroneous
I think it happens when MethodWriter#resizeInstructions is called (search for
cw.invalidFrames = true) this makes asm process the class again with
skip_frames (see ClassWriter#toByteArray).
After that there is some confusion in ClassWriter#newInvokeDynamicItem where it
seems to believe that it already has a bootstrap method and skips adding it.
For some reason this only seems to affect the first method.
The application to reproduce it can be found at:
https://drive.google.com/file/d/0Bw9yI1S_G81XSDBoLU9jZHFZSVk/view?usp=sharing
```https://gitlab.ow2.org/asm/asm/-/issues/317771Java 8 javac -parameters is causing RuntimeException at org.objectweb.asm.Met...2017-12-26T09:40:46ZvorburgerJava 8 javac -parameters is causing RuntimeException at org.objectweb.asm.MethodVisitor.visitParameter```
Java 8 javac's (new) -parameters (Quote e.g.
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html:
"Stores formal parameter names of constructors and methods in the generated
class file so that the method java.lan...```
Java 8 javac's (new) -parameters (Quote e.g.
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html:
"Stores formal parameter names of constructors and methods in the generated
class file so that the method java.lang.reflect.Executable.getParameters from
the Reflection API can retrieve them.") appears to cause this problem:
Caused by: java.lang.RuntimeException
at org.objectweb.asm.MethodVisitor.visitParameter(Unknown Source)
at org.objectweb.asm.ClassReader.b(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at
org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.readClass(AbstractWovenProxyAdapter.java:683)
at
org.apache.aries.proxy.impl.interfaces.InterfaceCombiningClassAdapter.generateBytes(InterfaceCombiningClassAdapter.java:109)
at
org.apache.aries.proxy.impl.interfaces.ProxyClassLoader.createProxyClass(ProxyClassLoader.java:156)
at
org.apache.aries.proxy.impl.interfaces.InterfaceProxyGenerator.getProxyInstance(InterfaceProxyGenerator.java:95)
at
org.apache.aries.proxy.impl.AsmProxyManager.createNewProxy(AsmProxyManager.java:80)
at
org.apache.aries.proxy.impl.AbstractProxyManager.createDelegatingInterceptingProxy(AbstractProxyManager.java:75)
at
org.apache.aries.proxy.impl.AbstractProxyManager.createDelegatingProxy(AbstractProxyManager.java:40)
at
org.apache.aries.blueprint.container.AbstractServiceReferenceRecipe.createProxy(AbstractServiceReferenceRecipe.java:332)
at
org.apache.aries.blueprint.container.ReferenceRecipe.internalCreate(ReferenceRecipe.java:107)
Originally found in https://bugs.opendaylight.org/show_bug.cgi?id=6523
```https://gitlab.ow2.org/asm/asm/-/issues/317601Packaging problems in asm2017-12-26T09:52:12ZbriantoppingPackaging problems in asm```
While deploying asm, I found the library doing a dynamic load of
org.objectweb.asm.commons.AdviceAdapter. Interestingly, that code is in the source jar but not in the
binary. Further digging shows the class in asm-commons.
There ...```
While deploying asm, I found the library doing a dynamic load of
org.objectweb.asm.commons.AdviceAdapter. Interestingly, that code is in the source jar but not in the
binary. Further digging shows the class in asm-commons.
There are probably two problems here:
1) https://repo1.maven.org/maven2/org/ow2/asm/asm/5.0.4/asm-5.0.4.pom should have an optional scope
dependency from asm to asm-commons
2) The source for asm and it's source jar needs to be checked for 1:1 correlations between the two artifacts.
```https://gitlab.ow2.org/asm/asm/-/issues/317769ClassReader throws ArrayIndexOutOfBoundsException when reading specific modul...2017-12-26T09:41:49ZadannClassReader throws ArrayIndexOutOfBoundsException when reading specific modul-info.class```
I'm using asm-debug-all-6.0_ALPHA.jar for reading modules of the upcoming JDK9.
Therefore, I'm reading module-info classes within my program.
However, on some module-info.class files the ClassReader throws an
ArrayIndexOutOfBoundsEx...```
I'm using asm-debug-all-6.0_ALPHA.jar for reading modules of the upcoming JDK9.
Therefore, I'm reading module-info classes within my program.
However, on some module-info.class files the ClassReader throws an
ArrayIndexOutOfBoundsException in Method readModule when visiting the exports
of a module-info.class file.
In particular, I've experienced this Exception when reading the
module-info.class of the following modules:
- java.compiler
- java.corba
- java.desktop
- java.instrument
- java.management
- java.base
- java.naming
- java.rmi
- java.security.jgss
- java.security.sasl
- java.sql
- java.xml
For the following modules, I get NO exception
- java.logging
- java.activation
- java.annotations.common
- java.compact1
- java.compact2
- java.compact3
- java.httpclient
- java.prefs
- java.scripting
- java.se
- java.se.ee
I've attached a test-case to reproduce the exception when reading
java.base/module-info.class
```https://gitlab.ow2.org/asm/asm/-/issues/317602Asmifier does not recognize null value for TypePath2017-12-26T09:51:51ZraphwAsmifier does not recognize null value for TypePath```
The Asmifier does not consider the possibility that a TypePath for a type
annotation can be null an renders incorrect example code.
A patch is attached.
``````
The Asmifier does not consider the possibility that a TypePath for a type
annotation can be null an renders incorrect example code.
A patch is attached.
```https://gitlab.ow2.org/asm/asm/-/issues/317607Calling add or set on an InsnListIterator throws NullPointerException when at...2017-12-26T09:50:18ZnmeyeringCalling add or set on an InsnListIterator throws NullPointerException when at end of list```
This applies to version 5.0.3 and but the bug seems to be present in current svn
trunk.
The following code throws a NullPointerException:
public static void main(String[] args)
{
final InsnList insnList = new InsnList();
fina...```
This applies to version 5.0.3 and but the bug seems to be present in current svn
trunk.
The following code throws a NullPointerException:
public static void main(String[] args)
{
final InsnList insnList = new InsnList();
final LabelNode node = new LabelNode(new Label());
insnList.add(node);
final ListIterator insnIter = insnList.iterator();
assert insnIter.next() != null;
insnIter.add(node); // NPE
// insnIter.set(node); // also causes NPE
}
According to the ListIterator interface, calling add when hasNext() returns
false should still add the element after the last list element.
However here it calls insertBefore(next, o), which tries to access next.prev,
which fails because next is null.
```https://gitlab.ow2.org/asm/asm/-/issues/317768ClassReader mishandles primitive class as bootstrap method argument2017-12-26T09:42:22ZbjkailClassReader mishandles primitive class as bootstrap method argument```
As reported on StackOverflow
(http://stackoverflow.com/questions/38809101/asm-cannot-pass-type-int-type-
as-constant-bootstrap-method-argument), if a Type representing a primitive
class (e.g., Type.INT_TYPE) is used as a bootstrap ...```
As reported on StackOverflow
(http://stackoverflow.com/questions/38809101/asm-cannot-pass-type-int-type-
as-constant-bootstrap-method-argument), if a Type representing a primitive
class (e.g., Type.INT_TYPE) is used as a bootstrap method argument, then
ClassReader reads it as an object type rather than a primitive type (e.g.,
type.getSort() == Type.OBJECT rather than type.getSort() == Type.INT).
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(Opcodes.V1_8, 0, "c", null, null, null);
MethodVisitor mv = cw.visitMethod(0, "m", "()V", null, null);
mv.visitInvokeDynamicInsn("foo", "(I)I",
new Handle(Opcodes.H_INVOKESTATIC, "o", "n", "()Ljava/lang/Object;"),
Type.INT_TYPE);
mv.visitEnd();
cw.visitEnd();
new ClassReader(cw.toByteArray()).accept(new ClassVisitor(Opcodes.ASM5) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
return new MethodVisitor(Opcodes.ASM5) {
@Override
public void visitInvokeDynamicInsn(String name, String desc,
Handle bsm, Object... bsmArgs) {
System.err.println(Arrays.toString(bsmArgs));
}
};
}
}, 0);
```https://gitlab.ow2.org/asm/asm/-/issues/317553StaticInitMerger breaks interfaces2017-12-26T10:01:31ZhoescheleStaticInitMerger breaks interfaces```
With a chain of ClassReader->StaticInitMerger->ClassWriter interfaces like this
http://grepcode.com/file_/repo1.maven.org/maven2/net.java.dev.glazedlists/glazedlists_java15/1.8.0/ca/odell/glazedlists/util/concurrent/LockFactory.java/...```
With a chain of ClassReader->StaticInitMerger->ClassWriter interfaces like this
http://grepcode.com/file_/repo1.maven.org/maven2/net.java.dev.glazedlists/glazedlists_java15/1.8.0/ca/odell/glazedlists/util/concurrent/LockFactory.java/?v=source
are corrupted and the Java VM will complain about illegal modifiers for methods.
The scenario is the following:
Some interfaces have a static fields which are assigned values that require
method calls. In bytecode this non-trivial assignment is compiled to a <clinit>
(however explicit static initializers in interfaces are not allowed by the Java
compiler).
StaticInitMerger simply renames all static initializers it finds and calls them
all in the single static initializer it creates.
In the case of the mentioned interface this results in one additional
non-abstract method in the interface which is not allowed by the Java VM. To
fix this special case we might want to combine/inline all initializers into a
single one in order to fix this problem.
I know that fields in interfaces are considered as bad practice by many
developers but this unfortunately happens in quite a lot of libraries which I
cannot simply ignore/replace.
```https://gitlab.ow2.org/asm/asm/-/issues/317551Frames are re-calculated for Large Methods2017-12-26T10:01:58ZmarchofFrames are re-calculated for Large Methods```
For certain large methods ASM enforces re-calculation of stackmap frames even
if COMPUTE_FRAMES is not specified. This in turn causes the ClassWriter to load
some of the types used in the instrumented class due to the call of the
get...```
For certain large methods ASM enforces re-calculation of stackmap frames even
if COMPUTE_FRAMES is not specified. This in turn causes the ClassWriter to load
some of the types used in the instrumented class due to the call of the
getCommonSuperClass() method.
In environments where the classes cannot be loaded into the JVM (or are not
available at all) this blocks the processing of certain class files.
The re-calculation is caused by this code in MethodWriter:
/*
* Resizing an existing stack map frame table is really hard.
* Not only the table must be parsed to update the offets, but
* new frames may be needed for jump instructions that were
* inserted by this method. And updating the offsets or
* inserting frames can change the format of the following
* frames, in case of packed frames. In practice the whole table
* must be recomputed. For this the frames are marked as
* potentially invalid. This will cause the whole class to be
* reread and rewritten with the COMPUTE_FRAMES option (see the
* ClassWriter.toByteArray method). This is not very efficient
* but is much easier and requires much less code than any other
* method I can think of.
*/
cw.invalidFrames = true;
As this is a "show stopper" for many users of our library (JaCoCo code
coverage) is there a chance to remove this workaround? Can we help to work on
this?
Thx,
-marc
```https://gitlab.ow2.org/asm/asm/-/issues/317630Frames are re-calculated for Large Methods2018-01-20T15:31:52ZEvgeny MandrikovFrames are re-calculated for Large Methods```
ASM Version: 5.1.0
The problem has been already described by Marc Hoffmann in #317551 which
contains patch, which was not verified and was not applied.
Together with Marc we made a reproducer for this case - see
https://github.c...```
ASM Version: 5.1.0
The problem has been already described by Marc Hoffmann in #317551 which
contains patch, which was not verified and was not applied.
Together with Marc we made a reproducer for this case - see
https://github.com/jacoco/jacoco/pull/177#issuecomment-222227425
And unfortunately patch causes NPE:
Exception in thread "main" java.lang.NullPointerException
at org.objectweb.asm.Frame.push(Frame.java:691)
at org.objectweb.asm.Frame.execute(Frame.java:978)
at org.objectweb.asm.CurrentFrame.execute(CurrentFrame.java:50)
at org.objectweb.asm.MethodWriter.visitInsn(MethodWriter.java:747)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1363)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1032)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:708)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:521)
at org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:1005)
at ResizeInstructions.main(ResizeInstructions.java:62)
Reproducer of this NPE attached.
```https://gitlab.ow2.org/asm/asm/-/issues/317554Missing Java 8 support in ClassReader2017-12-26T10:01:12ZraffigMissing Java 8 support in ClassReader```
Regards version 5.0.3
In this method:
org.objectweb.asm.ClassReader.ClassReader(byte[], int, int)
There is a fragment:
if (readShort(off + 6) > Opcodes.V1_7) {
throw new IllegalArgumentException();
}
(...```
Regards version 5.0.3
In this method:
org.objectweb.asm.ClassReader.ClassReader(byte[], int, int)
There is a fragment:
if (readShort(off + 6) > Opcodes.V1_7) {
throw new IllegalArgumentException();
}
(lines 169-171)
It seems that support for Java 8 is missing here.
```https://gitlab.ow2.org/asm/asm/-/issues/317593ClassReader.accept throws IndexOutOfBoundsException2017-12-26T09:53:04ZsafedkClassReader.accept throws IndexOutOfBoundsException```
Hi,
I'm using asm 5.0.4
I'm trying to read the attached class file using this code:
jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = ...```
Hi,
I'm using asm 5.0.4
I'm trying to read the attached class file using this code:
jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String entryName = entry.getName();
if (entryName.endsWith(".class")) {
ClassNode classNode = new ClassNode();
InputStream classFileInputStream = jarFile.getInputStream(entry);
try {
ClassReader classReader = new ClassReader(classFileInputStream);
classReader.accept(classNode, 0);
} finally {
classFileInputStream.close();
}
}
}
and I get this exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.b(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
......
Can you please advise?
```https://gitlab.ow2.org/asm/asm/-/issues/317584Array index out of bounds on latest Java2017-12-26T09:54:44ZgudenauArray index out of bounds on latest Java```
When using a ClassWriter to write a
ClassNode to a byte array an array of
length 0 has its first index read,
causing an exception.
Example:
byte[] classData =
getClassData("test");
ClassReader classReader = new
ClassReader(clas...```
When using a ClassWriter to write a
ClassNode to a byte array an array of
length 0 has its first index read,
causing an exception.
Example:
byte[] classData =
getClassData("test");
ClassReader classReader = new
ClassReader(classData);
ClassNode classNode = new
ClassNode();
classReader.accept(classNode, 0);
ClassWriter classWriter = new
ClassWriter(0);
classNode.accept(classWriter); //
Exception thrown here
return classWriter.toByteArray();
```https://gitlab.ow2.org/asm/asm/-/issues/317600Bad behavior of Type utility class with anonymously loaded classes2017-12-26T09:52:33ZraphwBad behavior of Type utility class with anonymously loaded classes```
Anonymous loaded classes (via sun.misc.Unsafe) have a different naming schema
where a name is called:
foo.Bar/12345
The utilities of the Type class do not properly account to this possibile
naming schema and do not return the right...```
Anonymous loaded classes (via sun.misc.Unsafe) have a different naming schema
where a name is called:
foo.Bar/12345
The utilities of the Type class do not properly account to this possibile
naming schema and do not return the right names for such classes.
```https://gitlab.ow2.org/asm/asm/-/issues/317583flagThisUninit not correctly computed for inserted try-finally block?2017-12-26T09:55:31ZyilongliflagThisUninit not correctly computed for inserted try-finally block?```
Hi,
I am using ASM to wrap method call into try-finally block in order to log the
start and end events of that method. For example, I am transforming "foo()"
into "try { logFooStart(); foo(); } finally { logFooEnd(); }". Now I am ...```
Hi,
I am using ASM to wrap method call into try-finally block in order to log the
start and end events of that method. For example, I am transforming "foo()"
into "try { logFooStart(); foo(); } finally { logFooEnd(); }". Now I am running
into a java.lang.VerifyError when the method call to wrap is a `this`
constructor.
Here is my Test class:
package instrumentation;
public class Test {
public Test(Test t) { this(); }
public Test() { }
public static void main(String[] args) {
new Test(null);
}
}
My code to insert the try-finally block looks rough like this:
/* Wrap the method call instruction into a try-finally block with logging code.
*
* LOG_INVOKE_METHOD
* L0:
* visitMethodInsn(opcode, owner, name, desc, itf)
* LOG_FINISH_METHOD
* goto L2
* L1:
* LOG_FINISH_METHOD
* throw exception
* L2:
* ...
*/
mv.push(locId) // push an int to the stack
invokeRtnMethod(LOG_INVOKE_METHOD); // my code to log event
Label l0 = mv.mark();
mv.visitMethodInsn(opcode, owner, name, desc, itf);
mv.push(locId);
invokeRtnMethod(LOG_FINISH_METHOD);
Label l2 = mv.newLabel();
mv.goTo(l2);
Label l1 = mv.mark();
mv.catchException(l0, l1, null);
mv.push(locId);
invokeRtnMethod(LOG_FINISH_METHOD);
mv.throwException();
mv.mark(l2);
`mv` is a GeneratorAdaptor and the underlying ClassWriter is constructed with
flag COMPUTE_FRAMES.
Here is the bytecode of the transformed Test constructor:
public instrumentation.Test(instrumentation.Test);
descriptor: (Linstrumentation/Test;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: sipush 137
4: invokestatic #30 // Method
com/runtimeverification/rvpredict/runtime/RVPredictRuntime.logInvokeMethod:(I)V
7: invokespecial #8 // Method "<init>":()V
10: sipush 137
13: invokestatic #33 // Method
com/runtimeverification/rvpredict/runtime/RVPredictRuntime.logFinishMethod:(I)V
16: goto 26
19: sipush 137
22: invokestatic #33 // Method
com/runtimeverification/rvpredict/runtime/RVPredictRuntime.logFinishMethod:(I)V
25: athrow
26: return
Exception table:
from to target type
7 19 19 any
LocalVariableTable:
Start Length Slot Name Signature
0 27 0 this Linstrumentation/Test;
0 27 1 t Linstrumentation/Test;
LineNumberTable:
line 6: 0
line 7: 26
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 19
locals = [ top, class instrumentation/Test ]
stack = [ class java/lang/Throwable ]
frame_type = 255 /* full_frame */
offset_delta = 6
locals = [ class instrumentation/Test, class instrumentation/Test ]
stack = []
And here is the java.lang.VerifyError I get:
Exception in thread "main" java.lang.VerifyError: Stack map does not match the
one at exception handler 19
Exception Details:
Location:
instrumentation/Test.<init>(Linstrumentation/Test;)V @19: sipush
Reason:
Current frame's flags are not assignable to stack map frame's.
Current Frame:
bci: @7
flags: { flagThisUninit }
locals: { uninitializedThis, 'instrumentation/Test' }
stack: { 'java/lang/Throwable' }
Stackmap Frame:
bci: @19
flags: { }
locals: { top, 'instrumentation/Test' }
stack: { 'java/lang/Throwable' }
Bytecode:
0x0000000: 2a11 0089 b800 1eb7 0008 1100 89b8 0021
0x0000010: a700 0a11 0089 b800 21bf b1
Exception Handler Table:
bci [7, 19] => handler: 19
Stackmap Table:
full_frame(@19,{Top,Object[#1]},{Object[#35]})
full_frame(@26,{Object[#1],Object[#1]},{})
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at
sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at
sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
It would appear that `flagThisUninit` is not correctly computed for the
stackmap of the finally-block. Is it a bug of the ASM or am I just doing
invalid transformation?
Thanks!
Yilong
```https://gitlab.ow2.org/asm/asm/-/issues/317631LocalVariablesSorter.newLocal() return wrong next variable index2017-12-26T09:44:32Zc7yanLocalVariablesSorter.newLocal() return wrong next variable index```
I'm trying to use ASM4.1 (I have to use this version for some reason) to add
code before method exit. I am extending AdviceAdapter and following the
technique described in ”ASM 4.0 Guide” under 3.3.4 ”AdviceAdapter” p64-65. I
use Loc...```
I'm trying to use ASM4.1 (I have to use this version for some reason) to add
code before method exit. I am extending AdviceAdapter and following the
technique described in ”ASM 4.0 Guide” under 3.3.4 ”AdviceAdapter” p64-65. I
use LocalVariablesSorter (a superclass of AdviceAdapter) to add local variables.
I have a method “onAdd” that takes one arg and has two locals of its own. My
understanding is that the variable indexes 0 (this), 1 (arg) and 2 & 3
(existing locals) are already taken, and the LocalVariablesSorter.newLocal()
should give me a index 4 or larger. But instead, it gives 2 as first call in
the inserted code before method exit.
I have made a test case for this (I intentionally made the code with mutiple
variables to show the issue):
1. the method to add code before the exit:
public void onAdd(View v) {
String addedText = inputText.getText().toString();
inputTextDisplay.setText(String.format("%s :%s",
getString(R.string.text_added), addedText));
inputTextDisplay.setVisibility(View.VISIBLE);
/**
* the following code needs to be inserted
String s = getClass().getName();
int i = s.indexOf("$");
if (i != -1) {
s = s.substring(0, i);
}
View view = v.getRootView();
String packageName = v.getContext().getPackageName();
InstrumentationInterface.getInstance().performInstrumentation(
view, s, packageName, ActionType.VIEW_CLICK);
*/
}
2. the MethidExistAdapter extends AdviceAdapter to implement the code insertion
@Override
protected void onMethodExit(int opcode) {
if (opcode != Opcodes.ATHROW) {
/**
* Add the following code before return of the method onAdd:
String s = getClass().getName();
int i = s.indexOf("$");
if (i != -1) {
s = s.substring(0, i);
}
View view = v.getRootView();
String packageName = v.getContext().getPackageName();
InstrumentationInterface.getInstance().performInstrumentation(
view, s, packageName);
*/
mv.visitVarInsn(ALOAD, 0); //0 this, 1 - v
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass",
"()Ljava/lang/Class;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName",
"()Ljava/lang/String;");
int var1 = newLocal(Type.LONG_TYPE); //s variable 2
mv.visitVarInsn(ASTORE, var1); //2
mv.visitVarInsn(ALOAD, var1); //2
mv.visitLdcInsn("$");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "indexOf",
"(Ljava/lang/String;)I");
int var2 = newLocal(Type.INT_TYPE); //variable 3
mv.visitVarInsn(ISTORE, var2); //3
mv.visitVarInsn(ILOAD, var2); //3
mv.visitInsn(ICONST_M1);
Label label = new Label();
mv.visitJumpInsn(IF_ICMPEQ, label);
mv.visitVarInsn(ALOAD, var1); //2
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ILOAD, var2); //3
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring",
"(II)Ljava/lang/String;");
mv.visitVarInsn(ASTORE, var1); //2
mv.visitLabel(label);
mv.visitVarInsn(ALOAD, 1); // v
mv.visitMethodInsn(INVOKEVIRTUAL, "android/view/View", "getRootView",
"()Landroid/view/View;");
int var3 = newLocal(Type.LONG_TYPE); //variable index 4
mv.visitVarInsn(ASTORE, var3); // 4
mv.visitVarInsn(ALOAD, 1); // v
mv.visitMethodInsn(INVOKEVIRTUAL, "android/view/View", "getContext",
"()Landroid/content/Context;");
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/Context",
"getPackageName", "()Ljava/lang/String;");
int var4 = newLocal(Type.LONG_TYPE); //variable index 5
mv.visitVarInsn(ASTORE, var4); //5
mv.visitMethodInsn(INVOKESTATIC,
"com/ibm/haac/mac/util/InstrumentationInterface", "getInstance",
"()Lcom/ibm/haac/mac/util/InstrumentationInterface;");
mv.visitVarInsn(ALOAD, var3); //4
mv.visitVarInsn(ALOAD, var1); //2
mv.visitVarInsn(ALOAD, var4); //5
mv.visitFieldInsn(GETSTATIC,
"com/ibm/haac/mac/constants/InstrumentationUtil$ActionType", "VIEW_CLICK",
"Lcom/ibm/haac/mac/constants/InstrumentationUtil$ActionType;");
mv.visitMethodInsn(INVOKEVIRTUAL,
"com/ibm/haac/mac/util/InstrumentationInterface", "performInstrumentation",
"(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Lcom/ibm/haac/mac/constants/InstrumentationUtil$ActionType;)V");
System.out.println(var1 +"," +var2 +", " + var3 +","+var4);
}
super.onMethodExit(opcode);
}
3. After the code insertion, the code varies each time, but they all wrong,
and unable to pass the verification. Here is “onAdd” method from one of the
generated classed after decompilation:
public void onAdd(View view) {
view = inputText.getText().toString();
inputTextDisplay.setText(String.format("%s :%s", new Object[] {
getString(0x7f060005), view
}));
inputTextDisplay.setVisibility(0);
String s = getClass().getName();
int i = s.indexOf("$");
if(i != -1)
s = s.substring(0, i);
View view1 = view.getRootView();
String s1 = view.getContext().getPackageName();
InstrumentationInterface.getInstance().performInstrumentation(view1,
s, s1, com.ibm.haac.mac.constants.InstrumentationUtil.ActionType.VIEW_CLICK);
}
The method is totally screwed up. You can see the local variable is
overwritten even in the very first line (the view is rescued for String!!).
I include the following test code in the zip file:
CustomClassVistor: a class visitor class
TestMethodExitAdapter: implementation of insertion logic
CustomTest: test driver, containing the main, you can run the program.
MainActivity.class: a test java class. Please copy over to a local
folder, and modify the file path in the CustomTest to run.
NewMainActivity.class: generated class after the code insertion.
```https://gitlab.ow2.org/asm/asm/-/issues/317713ArrayIndexOutOfBoundException on certain Type Annotations2017-12-26T09:44:07ZctolkmitArrayIndexOutOfBoundException on certain Type Annotations```
I am using ASM 5.1 as part of JaCoCo 0.7.7 (jacoco-maven-plugin), and I get the
following exception when using some type annotations:
java.lang.instrument.IllegalClassFormatException: Error while instrumenting
class com/ennit/sal/...```
I am using ASM 5.1 as part of JaCoCo 0.7.7 (jacoco-maven-plugin), and I get the
following exception when using some type annotations:
java.lang.instrument.IllegalClassFormatException: Error while instrumenting
class com/ennit/sal/index/api/model/value/BinaryValue.
at
org.jacoco.agent.rt.internal_6da5971.CoverageTransformer.transform(CoverageTran
sformer.java:93)
at
sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at
sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at
com.ennit.sal.index.api.model.WritableRecordAutoTest.data(WritableRecordAutoTes
t.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.jav
a:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java
:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
47)
at
org.junit.runners.Parameterized.allParameters(Parameterized.java:280)
at org.junit.runners.Parameterized.<init>(Parameterized.java:248)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessor
Impl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructor
AccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at
org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:
104)
at
org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.ja
va:86)
at
org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at
org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDe
faultPossibilitiesBuilder.java:26)
at org.junit.runner.Computer.getRunner(Computer.java:40)
at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
at
org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at
org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
at org.junit.runners.Suite.<init>(Suite.java:81)
at org.junit.runner.Computer.getSuite(Computer.java:28)
at org.junit.runner.Request.classes(Request.java:75)
at org.junit.runner.Request.classes(Request.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.apache.maven.surefire.common.junit4.JUnit4Reflector.createRequest(JUnit4Ref
lector.java:63)
at
org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.createSuiteDescripti
on(JUnit4ProviderUtil.java:113)
at
org.apache.maven.surefire.junit4.JUnit4Provider.createTestsDescription(JUnit4Pr
ovider.java:257)
at
org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at
org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(F
orkedBooter.java:203)
at
org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.j
ava:155)
at
org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: java.io.IOException: Error while instrumenting class
com/ennit/sal/index/api/model/value/BinaryValue.
at
org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrumentError(In
strumenter.java:160)
at
org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrum
enter.java:111)
at
org.jacoco.agent.rt.internal_6da5971.CoverageTransformer.transform(CoverageTran
sformer.java:91)
... 52 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 70
at
org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.readLabel(ClassReader.java
:2184)
at
org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.readTypeAnnotations(ClassR
eader.java:1611)
at
org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.readCode(ClassReader.java:
1186)
at
org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.readMethod(ClassReader.jav
a:1017)
at
org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.accept(ClassReader.java:69
3)
at
org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.accept(ClassReader.java:50
6)
at
org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrum
enter.java:84)
at
org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrum
enter.java:108)
... 53 more
The code part in question is:
@Override
public int compareTo(final BinaryValue aOther) {
final byte @NonNull [] thisValue = getValue();
final byte @NonNull [] otherValue = aOther.getValue();
final int len = Math.min(thisValue.length, otherValue.length);
for (int i = 0; i < len; i++) {
final int c = Byte.compare(thisValue[i], otherValue[i]);
if (c != 0) {
return c;
}
}
// shorter value first, if prefixes are identical
return Integer.compare(thisValue.length, otherValue.length);
}
If I omit the @NonNull annotations on the arrays in this way:
@Override
public int compareTo(final BinaryValue aOther) {
final byte [] thisValue = getValue();
final byte [] otherValue = aOther.getValue();
final int len = Math.min(thisValue.length, otherValue.length);
for (int i = 0; i < len; i++) {
final int c = Byte.compare(thisValue[i], otherValue[i]);
if (c != 0) {
return c;
}
}
// shorter value first, if prefixes are identical
return Integer.compare(thisValue.length, otherValue.length);
}
Everything works fine
```https://gitlab.ow2.org/asm/asm/-/issues/317770ClassReader/ClassWriter producing less byte codes than original class file2017-12-26T09:41:03Zesheri3ClassReader/ClassWriter producing less byte codes than original class file```
Team,
I am using ClassReader and ClassWriter to generate bytecodes without making any
modifications to the original bytecodes. Given that there is no modification to the bytecodes
during the visiting process, I would expect the nu...```
Team,
I am using ClassReader and ClassWriter to generate bytecodes without making any
modifications to the original bytecodes. Given that there is no modification to the bytecodes
during the visiting process, I would expect the number of weaved byte codes to equal that of
the original byte codes. However, I have a handful of cases where this is not true. Is this a
known issue? Bug? Basic POC code below:
final byte[] originalCodes = Files.readAllBytes(/* some class file */);
final ClassReader reader = new ClassReader(originalCodes);
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
reader.accept(writer, 0);
final byte[] weavedCodes = writer.toByteArray();
assert(weavedCodes.length >= originalCodes.length); // fails
An example class that fails is from the Jackson Json library:
com/fasterxml/jackson/annotation/JsonAutoDetect$1.class
The weaved codes for this class is of length 1125 whereas the original byte code length is
1131. What might have been lost? Happy to attach faulty classes for tests if this is indeed a
new issue. Thanks and keep up the great work!
```https://gitlab.ow2.org/asm/asm/-/issues/317626AnnotationNode incorrectly process array values in 'visit(final String name, ...2018-01-21T08:00:13ZkammererAnnotationNode incorrectly process array values in 'visit(final String name, final Object value)' method```
According to javadoc 'AnnotationNode.values' field contains only simple values
or lists of them, but not arrays (except enum case).
Java doc of 'AnnotationVisitor.visit(final String name, final Object value)'
says that it accepts arr...```
According to javadoc 'AnnotationNode.values' field contains only simple values
or lists of them, but not arrays (except enum case).
Java doc of 'AnnotationVisitor.visit(final String name, final Object value)'
says that it accepts arrays and in such case it's a shortcut for 'visitArray'
and array elements iteration.
AnnotationNode do nothing to process such shortcuts and as result writes arrays
of primitives to 'values' field.
Simple case to reproduce: pass AnnotationNode to ClassReader
```https://gitlab.ow2.org/asm/asm/-/issues/317581Import-Package headers should denote version by setting the version attribute2017-12-26T09:55:47ZwouterbanckenImport-Package headers should denote version by setting the version attribute```
Currently the Import-Package headers of asm-analysis (asm-analysis.bnd), asm-commons
(asm-commons.bnd), asm-tree (asm-tree.bnd) and asm-util (asm-util.bnd) define the version
by using ':='.
Import-Package headers should set the ve...```
Currently the Import-Package headers of asm-analysis (asm-analysis.bnd), asm-commons
(asm-commons.bnd), asm-tree (asm-tree.bnd) and asm-util (asm-util.bnd) define the version
by using ':='.
Import-Package headers should set the version attribute by using a '=' (without a colon).
By using ':=' you are actually defining a custom directive instead of setting the existing
version attribute.
For example, the correct definition in asm-analysis.bnd would be
Import-Package: org.objectweb.asm.*;version="[${product.artifact},${product.artifact}]"
```https://gitlab.ow2.org/asm/asm/-/issues/317587ArrayIndexOutOfBoundsException while reading a class file2017-12-26T09:53:34ZmetlosArrayIndexOutOfBoundsException while reading a class file```
I have a simple class reader that I am using to read the structure of a class.
I get an ArrayIndexOutOfBoundsException when trying to use this to read class
com.ibm.icu.impl.data.LocaleElements_zh__PINYIN from icu4j version 2.6.1
(ht...```
I have a simple class reader that I am using to read the structure of a class.
I get an ArrayIndexOutOfBoundsException when trying to use this to read class
com.ibm.icu.impl.data.LocaleElements_zh__PINYIN from icu4j version 2.6.1
(http://search.maven.org/#artifactdetails|com.ibm.icu|icu4j|2.6.1|jar).
In the attached Maven project the "test.class" is a class file of the above
mentioned class.
Repro steps:
unzip the attached reproducer.zip and run:
mvn package exec:java -Dexec.mainClass=Main
```https://gitlab.ow2.org/asm/asm/-/issues/317579Signature Process in SignatureRemapper is Broken2017-12-26T09:56:42ZkuzukamiSignature Process in SignatureRemapper is Broken```
Hi, ASM development team.
I found a bug of RemappingSignatureAdapter contained in Remapper.
The reproduction code of bug reports a fully unknown class name
'java/lang/Object$Hoge' as a source of type mapping. This is apparent.
Af...```
Hi, ASM development team.
I found a bug of RemappingSignatureAdapter contained in Remapper.
The reproduction code of bug reports a fully unknown class name
'java/lang/Object$Hoge' as a source of type mapping. This is apparent.
After my debugging of code, I think that
a pair of new API of 'SignatureVisitor.visitTypeArguments()' and
'SignatureVisitor.visitTypeArguments()' must be added, and then some refactors
around "the case '<': " in 'SignatureReader#parseType()' are required to solve
this bug.
I want to confirm the direction of solution in this project
because my plan requires a big refactor and new set of API.
// public class Cls4_ArtAnother {
//
// public static class ClsX<T>{
// public class Hoge{
// }
// }
//
// public static class ClsY extends ClsX<Object>{
// public class Tako extends ClsX<Object>.Hoge{
// }
// }
//
// }
@Test
public void testBrokenSigProc(){
//Signature of Tako class
String clssig =
"Ltestpkg/Cls4_ArtAnother$ClsX<Ljava/lang/Object;>.Hoge;";
Remapper rm = new Remapper() {
@Override
public String mapType(String type) {
if ( type.equals( "java/lang/Object$Hoge" ) ) {
System.out.println(type);
}
return super.mapType(type);
}
};
rm.mapSignature(clssig, false);
}
```https://gitlab.ow2.org/asm/asm/-/issues/317624visitSource of ASM itself does not contain file names2017-12-26T09:46:40ZfommilvisitSource of ASM itself does not contain file names```
It looks like the source code file name is missing from your .class files (by
this I mean if ASM is applied to itself!).
This is making it extremely difficult (i.e. we'll need to write a custom
workaround) for us to be able to res...```
It looks like the source code file name is missing from your .class files (by
this I mean if ASM is applied to itself!).
This is making it extremely difficult (i.e. we'll need to write a custom
workaround) for us to be able to resolve the sources for a given FQN.
Also, it looks like the published source jars contain a double posting of the
actual sources? Very weird, I was looking at the source for SimpleRemapper (in
the commons) and the source was definitely appended to the existing source
(unless Emacs has a bug).
For an example of how we read this information see
https://github.com/ensime/ensime-
server/blob/master/core/src/main/scala/org/ensime/indexer/ClassfileIndexer.scala
#L64
```https://gitlab.ow2.org/asm/asm/-/issues/317578MethodWriter getSize() incorrect max code size check2017-12-26T09:57:05ZmederMethodWriter getSize() incorrect max code size check```
The code below should be checking if code.length is greather than 65535 (not
65536):
final int getSize() {
if (classReaderOffset != 0) {
return 6 + classReaderLength;
}
int size = 8;
...```
The code below should be checking if code.length is greather than 65535 (not
65536):
final int getSize() {
if (classReaderOffset != 0) {
return 6 + classReaderLength;
}
int size = 8;
if (code.length > 0) {
if (code.length > 65536) {
throw new RuntimeException("Method code too large!");
}
cw.newUTF8("Code");
size += 18 + code.length + 8 * handlerCount;
```https://gitlab.ow2.org/asm/asm/-/issues/317620Dependency convergence errors2017-12-26T09:47:30Zjebl01Dependency convergence errors```
When running my build with the maven-enforcer-plugin, I get the following convergence error
report:
Dependency convergence error for org.ow2.asm:asm:4.1 paths to dependency are:
+-<obfuscated-projectname>:0.1.5-SNAPSHOT
+-org.spr...```
When running my build with the maven-enforcer-plugin, I get the following convergence error
report:
Dependency convergence error for org.ow2.asm:asm:4.1 paths to dependency are:
+-<obfuscated-projectname>:0.1.5-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-jetty:1.3.2.RELEASE
+-org.eclipse.jetty.websocket:javax-websocket-server-impl:9.2.14.v20151106
+-org.eclipse.jetty:jetty-annotations:9.2.14.v20151106
+-org.ow2.asm:asm:4.1
and
+-<obfuscated-projectname>:0.1.5-SNAPSHOT
+-org.springframework.boot:spring-boot-starter-jetty:1.3.2.RELEASE
+-org.eclipse.jetty.websocket:javax-websocket-server-impl:9.2.14.v20151106
+-org.eclipse.jetty:jetty-annotations:9.2.14.v20151106
+-org.ow2.asm:asm-commons:4.1
+-org.ow2.asm:asm-tree:5.0.1
+-org.ow2.asm:asm:5.0.1
leads me to think that asm-commons:4.1 and asm:4.1 lives two completely separated lives? Is
this correct (and expected)? If so, It's a bit confusing...
A more expected dependency graph would be that asm-commons:4.1 had a transitive
dependency on asm:4.1 (not 5.0.1)
```https://gitlab.ow2.org/asm/asm/-/issues/317548Mistakes in API documentation of MethodVisitor and SignatureVisitor2017-12-26T10:02:12ZtrohovskyMistakes in API documentation of MethodVisitor and SignatureVisitor```
MethodVisitor
- visitParameterAnnotation is missing in the desciption of method calling order
- visitTryCatchAnnotation vs. current visitTryCatchBlockAnnotation
SignatureVisitor
- visitSuperclass vs. current visitSuperClass
``````
MethodVisitor
- visitParameterAnnotation is missing in the desciption of method calling order
- visitTryCatchAnnotation vs. current visitTryCatchBlockAnnotation
SignatureVisitor
- visitSuperclass vs. current visitSuperClass
```https://gitlab.ow2.org/asm/asm/-/issues/317576RemappingMethodAdapter requires expanded frames even for simple use cases2017-12-26T09:57:31ZraphwRemappingMethodAdapter requires expanded frames even for simple use cases```
A simple but common use case for the RemappingClassAdapter is the use of the
SimpleRemapper for renaming. The remapping does however require to hand over
expanded frames for allowing a generic processing as the LocalVariablesSorter
d...```
A simple but common use case for the RemappingClassAdapter is the use of the
SimpleRemapper for renaming. The remapping does however require to hand over
expanded frames for allowing a generic processing as the LocalVariablesSorter
demands this.
I do not quite understand why this is necessary as renaming does not require
the creation or the sorting of local variables. I understand that the
RemappingMethodAdapter and the LocalVariableSorter are quite connected in the
former class's implementation but I would like to have an option to avoid the
frame expansion for simple renaming.
Is this possible?
```https://gitlab.ow2.org/asm/asm/-/issues/317574Invalid jar artifacts published in objectweb and maven repository for 5.042017-12-26T09:57:48ZrsshInvalid jar artifacts published in objectweb and maven repository for 5.04```
Look;s like jars, published in maven central and object web repository is compiled with java-
1.2 output mode. (0.46 class file version).
So, generic information about one is missing.
To reproduce, clear local maven repository an...```
Look;s like jars, published in maven central and object web repository is compiled with java-
1.2 output mode. (0.46 class file version).
So, generic information about one is missing.
To reproduce, clear local maven repository and try to checkout and compile test maven
project from https://github.com/rssh/ASMDependencyCheck
```https://gitlab.ow2.org/asm/asm/-/issues/317545Asm eat linenumbers if there are several of them on one label2017-12-26T10:02:52ZkammererAsm eat linenumbers if there are several of them on one label```
Java bytecode allows to write several linenumbers on one label (see example
below) but asm keeps only one line. So it's impossible read and verify all
bytecode information using ClassReader.MethodVisitor
LineNumberTable:
...```
Java bytecode allows to write several linenumbers on one label (see example
below) but asm keeps only one line. So it's impossible read and verify all
bytecode information using ClassReader.MethodVisitor
LineNumberTable:
line 20: 0
line 21: 5
line 23: 27
line 20: 46
line 26: 46
line 27: 51
line 29: 72
line 26: 90
ClassReader.MethodVisitor.visitLineNumber say that label 46 corresponds only to
line 26 and skips entry for line 20: 46
```https://gitlab.ow2.org/asm/asm/-/issues/317569AnnotationVisitor prevents method injection2017-12-26T09:58:22ZbsantosAnnotationVisitor prevents method injection```
I have the following Test class:
@Features(value = {"baa.boo", "foo.boo"})
public class JavaTest {
@Test
public void shouldExecuteJavaTest() {
System.out.println("Simple Java Test.");
}
}
And an ASM class visitor that p...```
I have the following Test class:
@Features(value = {"baa.boo", "foo.boo"})
public class JavaTest {
@Test
public void shouldExecuteJavaTest() {
System.out.println("Simple Java Test.");
}
}
And an ASM class visitor that process class annotations and inject a method on visitEnd:
public class TestInjectorVisitor extends ClassVisitor {
private List<String> features = new ArrayList<>();
private ClassVisitor cw;
public TestInjectorVisitor(final ClassVisitor cv) {
super(ASM4, cv);
cw = cv;
}
@Override
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean
runtimeVisible) {
if (descriptor.equals("Lcom/github/bmsantos/asm/Features;")) {
return new AnnotationVisitor(ASM4, super.visitAnnotation(descriptor, runtimeVisible))
{
@Override
public AnnotationVisitor visitArray(final String name) {
if ("value".equals(name)) {
return new AnnotationVisitor(ASM4, super.visitArray(name)) {
@Override
public void visit(final String name, final Object value) {
features.add(value.toString());
super.visit(name, value);
}
};
}
return super.visitArray(name);
}
};
}
return super.visitAnnotation(descriptor, runtimeVisible);
}
@Override
public void visitEnd() {
for (final String feature : features) {
System.err.println("Found feature: " + feature);
}
injectJavaTestMethod();
super.visitEnd();
}
private void injectJavaTestMethod() {
final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "shouldDisplayJavaMonkey", "
()V", null, null);
final AnnotationVisitor av = mv.visitAnnotation("Lorg/junit/Test;", true);
av.visitEnd();
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("Hello Java Monkeys!");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "
(Ljava/lang/String;)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
}
The method is successfully injected when the Features annotation is not present on the
JUnit test.
Is this an issue or am I just overlooking something?
Thanks,
Bruno
```https://gitlab.ow2.org/asm/asm/-/issues/317618ASM 5.0.4 and 5.1 doesn't support Java 5 bytecode fully (ArrayArrayIndexOutOf...2017-12-26T09:48:14ZSergey PatrikeevASM 5.0.4 and 5.1 doesn't support Java 5 bytecode fully (ArrayArrayIndexOutOfBoundsException: 2304)```
I'm trying to parse the given bytecode (see an attachment) with ASM 5.0.4 or
5.1.
I use the following code:
ClassNode node = new ClassNode();
new ClassReader(getFilePath("RegexUtil.class"))).accept(node, 0);
System.out.println(node....```
I'm trying to parse the given bytecode (see an attachment) with ASM 5.0.4 or
5.1.
I use the following code:
ClassNode node = new ClassNode();
new ClassReader(getFilePath("RegexUtil.class"))).accept(node, 0);
System.out.println(node.name);
The following exception is thrown (see an attachment)
java.lang.ArrayIndexOutOfBoundsException: 2304
I have used "javap" to determine the JDK version. It is 1.5.
I then have tried to use "asm:asm-all:3.3.1" (instead of "org.ow2.asm:asm-
all:5.1") and it helped!
Unfortunately I have to parse the JDK 8 bytecode too, so I can't just use the
old version.
Sorry for duplicate if I have overlooked.
I also might have mixed up the Component/s
```https://gitlab.ow2.org/asm/asm/-/issues/317547incorrect owner argument of ASM MethodWriter#visitFieldInsn when dealing with...2017-12-26T10:02:38Zyilongliincorrect owner argument of ASM MethodWriter#visitFieldInsn when dealing with static field```
Consider the following example:
public class Test extends Test2 {
public static void main(String[] args) {
staticVariable = true;
Test2.staticVariable = true;
}
}
class Test2 {
static boolean staticVaria...```
Consider the following example:
public class Test extends Test2 {
public static void main(String[] args) {
staticVariable = true;
Test2.staticVariable = true;
}
}
class Test2 {
static boolean staticVariable;
}
The owner argument in MethodWriter#visitFieldInsn(int opcode, String owner,
String name, String desc) for the first access of staticVariable is "Test" while
the second one is "Test2".
This doesn't look right to me. I am using ASM 5.02.
```https://gitlab.ow2.org/asm/asm/-/issues/317603"RemappingClassAdapter" can cause re-assignment of local slots2017-12-26T09:51:26Zcirclespainter"RemappingClassAdapter" can cause re-assignment of local slots```
Full description and small project that reproduces the issue:
https://github.com/circlespainter/asm-relocate-localvars-bug
From README:
When using [ASM](http://asm.ow2.org/)'s `RemappingClassAdapter`, even with an
empty remappi...```
Full description and small project that reproduces the issue:
https://github.com/circlespainter/asm-relocate-localvars-bug
From README:
When using [ASM](http://asm.ow2.org/)'s `RemappingClassAdapter`, even with an
empty remapping, a method's locals can be relocated so that (seemingly) the
first appearing in the bytecode sequence will get lower slots.
This is an issue for transforming logic that relies on local slot stability.
This issue is inherited f.e. by the [Gradle Shadow plugin]
(https://github.com/johnrengelman/shadow).
```https://gitlab.ow2.org/asm/asm/-/issues/317567SerialVersionUIDAdder issues2017-12-26T09:58:58ZztandresSerialVersionUIDAdder issues```
We are using a custom version of SerialVersionUIDAdder. The issues with the
original are the following:
1) serialVersionUID should be 0L for enums:
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html#646...```
We are using a custom version of SerialVersionUIDAdder. The issues with the
original are the following:
1) serialVersionUID should be 0L for enums:
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469
> Similarly, any serialPersistentFields or serialVersionUID field declarations
are also ignored--all enum types have a fixed serialVersionUID of 0L
But with ASM it will be a number.
Javas util "serialver" gives a 0L for serialVersionUID.
2) serialVersionUID should be computed to interfaces because interfaces can
have a serialVersionUID field.
"serialver" gives a default serialVersionUID.
2*) When computing serialVersionUID for an interface with 0 methods. Then the
class should be counted as non-abstract, this can be checked by comparing
results with "serialver".
In code:
visit(...):
computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
->
computeSVUID = (access & Opcodes.ACC_ENUM) == 0;
computeSVUID():
before dos.writeInt
int access = this.access;
if ((access & Opcodes.ACC_INTERFACE) != 0)
access = (svuidMethods.size() > 0) ? (access | Opcodes.ACC_ABSTRACT) : (access
& ~Opcodes.ACC_ABSTRACT);
```https://gitlab.ow2.org/asm/asm/-/issues/317621Type.getReturnType(desc) returns wrong for types with parenthesis in name2018-01-13T14:04:48ZjemrType.getReturnType(desc) returns wrong for types with parenthesis in name```
Parenthesis are legal characters for classes, which can causes issues with
Type.getReturnType() if used as a parameter for a method (for instance Weld
can create classes with parenthesis in the name)
Example:
String methodDesc = "...```
Parenthesis are legal characters for classes, which can causes issues with
Type.getReturnType() if used as a parameter for a method (for instance Weld
can create classes with parenthesis in the name)
Example:
String methodDesc = "(Lsome/klass_method();)I";
System.out.println(Type.getReturnType(methodDesc));
Should print "I", but instead prints ";)I"
```https://gitlab.ow2.org/asm/asm/-/issues/317541Java 8 + hibernate validator = IllegalArgumentException2017-12-26T10:03:19ZmikecurwenJava 8 + hibernate validator = IllegalArgumentException```
I've include a small project which replicates the issue.
Using java 1.8.0_20 , asm 5.0.3 and hibernate validator 5.1.2.Final (see
pom.xml for other info).
The stacktrace is:
java.lang.IllegalArgumentException
at net.sf.cglib.a...```
I've include a small project which replicates the issue.
Using java 1.8.0_20 , asm 5.0.3 and hibernate validator 5.1.2.Final (see
pom.xml for other info).
The stacktrace is:
java.lang.IllegalArgumentException
at net.sf.cglib.asm.ClassReader.<init>(Unknown Source)
at net.sf.cglib.asm.ClassReader.<init>(Unknown Source)
at net.sf.cglib.asm.ClassReader.<init>(Unknown Source)
at
net.sf.cglib.proxy.BridgeMethodResolver.resolveAll(BridgeMethodResolver.java:61
)
at net.sf.cglib.proxy.Enhancer.emitMethods(Enhancer.java:911)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:498)
at
net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.ja
va:25)
at
net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216
)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at
org.easymock.internal.ClassProxyFactory.createProxy(ClassProxyFactory.java:175)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:114)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:88)
at org.easymock.internal.MockBuilder.createMock(MockBuilder.java:206)
at org.easymock.internal.MockBuilder.createMock(MockBuilder.java:219)
at org.easymock.internal.MockBuilder.createMock(MockBuilder.java:188)
at
com.company.app.module.constraint.validator.FooValidatorNoJava8Test.createParti
alMock(FooValidatorNoJava8Test.java:38)
at
com.company.app.module.constraint.validator.FooValidatorNoJava8Test.testValid(F
ooValidatorNoJava8Test.java:25
```https://gitlab.ow2.org/asm/asm/-/issues/317561ArrayIndexOutOfBoundsException in ClassReader2017-12-26T09:59:19ZadligoArrayIndexOutOfBoundsException in ClassReader```
Hi,
I was ran into a ArrayIndexOutOfBoundException when trying to read the attached class;
Here is the stacktrace;
java.lang.ArrayIndexOutOfBoundsException: 6
at org.objectweb.asm.ClassReader.readShort(ClassReader.java:2326)
a...```
Hi,
I was ran into a ArrayIndexOutOfBoundException when trying to read the attached class;
Here is the stacktrace;
java.lang.ArrayIndexOutOfBoundsException: 6
at org.objectweb.asm.ClassReader.readShort(ClassReader.java:2326)
at org.objectweb.asm.ClassReader.<init>(ClassReader.java:169)
at org.objectweb.asm.ClassReader.<init>(ClassReader.java:153)
at org.objectweb.asm.ClassReader.<init>(ClassReader.java:424)
TIA,
Scott
```https://gitlab.ow2.org/asm/asm/-/issues/317616Misleading comment in ClassWriter2017-12-26T09:48:35ZdreissMisleading comment in ClassWriter```
The javadoc comment for a ClassWriter constructor says "This means that the
maximum stack size nor the stack frames will be computed for these methods".
This should say "This means that *neither* the maximum stack size nor the stack...```
The javadoc comment for a ClassWriter constructor says "This means that the
maximum stack size nor the stack frames will be computed for these methods".
This should say "This means that *neither* the maximum stack size nor the stack
frames will be computed for these methods." (without the stars).
```https://gitlab.ow2.org/asm/asm/-/issues/317539TypePath not adequately supporting types w/ >10 type arguments2017-12-26T10:03:36Zjhumphries131TypePath not adequately supporting types w/ >10 type arguments```
In ASM 5.0.3:
TypePath.fromString() and TypePath.toString() both describe path elements for navigating type arguments
of a parameterized type as a single decimal digit. This doesn't adequately support types that have > 10
type arg...```
In ASM 5.0.3:
TypePath.fromString() and TypePath.toString() both describe path elements for navigating type arguments
of a parameterized type as a single decimal digit. This doesn't adequately support types that have > 10
type arguments.
Looking at the javadoc and even the source doesn't reveal anything obvious about how values > 10th (e.g.
> '9') should be handled.
The source for TypePath.fromString() looks like it reads a sequence of decimal digits as a single "type
argument" path element. But then there's no obvious separator between multiple type argument path
elements (though the code looks like it would accept anything other than a decimal digit or ".", "*", or "]").
The source for TypePath.toString(), on the other hand, looks like it will not correctly handle values for type
argument indices > '9'. It simply concatenates adjacent path elements. So a path of:
type_argument(1), type_argument(0)
of a nested generic type is indistinguishable from the path:
type_argument(10)
of a generic type with >10 type arguments.
When using ASMifier to generate source code for a class, it looks like it is trying to use adjacent single
decimal digits for each path step (which won't actually work since fromString() will combine them into a
single step). If any single step has value > '9', then it inserts period separators (e.g. ".10.1" is the type
argument at index 11 and then 1 where as "101" is the type argument at index 1 then 0 then 1). However,
periods are defined in the toString() doc (and in the actual implementation code) to mean
nested/enclosed type path elements, not type arguments.
We can see the above ambiguity in action with the following sample code:
----
import java.io.PrintWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.TraceClassVisitor;
public class TypePathBug {
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface A {
}
class T<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> {
}
class U<X, Y, Z> extends T<X, Map<@A Y, Z>, X, Y, Z, X, Y, Z, X, Y, @A Z, X> {
}
public static void main(String args[]) throws Exception {
new ClassReader(U.class.getName().replace('.', '/')).accept(
new TraceClassVisitor(null, new ASMifier(),
new PrintWriter(System.out)), 0);
}
}
----
The resulting output generates code for the two @A annotations that is identical and thus
indistinguishable -- which means it cannot be correct since they are distinct/different type paths. Here is
the code generated for both type annotations:
{
av0 = cw.visitTypeAnnotation(285212416, TypePath.fromString(".10"), "LTypePathBug$A;", true);
av0.visitEnd();
}
----
Were I propose a fix: decimal path elements that indicate type parameter indices are terminated with a
semicolon. All of TypePath.toString(), TypePath.fromString(), and ASMifier would need to be updated. The
above ambiguous type path, ".10" would instead be represented as "1;0;" for the first occurrence of @A
and "10;" for the second. TypePath.fromString() can be lenient and not require ";" termination if it instead
encounters end-of-string, ".", "[", or "*".
```https://gitlab.ow2.org/asm/asm/-/issues/317538AnnotationNode in ASM 5.0.3 does not handle null returned from AnnotationVisi...2018-01-21T08:20:17ZLubomir BulejAnnotationNode in ASM 5.0.3 does not handle null returned from AnnotationVisitor correctly.```
AnnotationNode in ASM 5.0.3 does not handle null returned from
AnnotationVisitor correctly. While the documentation says that
AnnotationVisitor.visitArray(String) can return null , the
AnnotationNode.accept(AnnotationVisitor, String,...```
AnnotationNode in ASM 5.0.3 does not handle null returned from
AnnotationVisitor correctly. While the documentation says that
AnnotationVisitor.visitArray(String) can return null , the
AnnotationNode.accept(AnnotationVisitor, String, Object) method calls
AnnotationVisitor.visitEnd() on a potentially null visitor in the part that
handles List values.
Suggested fix to AnnotationNode.accept(AnnotationVisitor, String, Object):
...
} else if (value instanceof List) {
AnnotationVisitor v = av.visitArray(name);
if (v != null) {
List array = (List) value;
for (int j = 0; j < array.size(); ++j) {
accept(v, null, array.get(j));
}
v.visitEnd();
}
} else {
...
```https://gitlab.ow2.org/asm/asm/-/issues/317537Wrong tryCatch block sorting2017-12-26T10:04:02ZkammererWrong tryCatch block sorting```
TryCatchBlockSorter:
Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() {
public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
int len1 = blockLength(t1);
...```
TryCatchBlockSorter:
Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() {
public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
int len1 = blockLength(t1);
int len2 = blockLength(t2);
return len1 - len2;
}
private int blockLength(TryCatchBlockNode block) {
int startidx = instructions.indexOf(block.start);
int endidx = instructions.indexOf(block.end);
return endidx - startidx;
}
};
after node sorting node for default catch handler could occur before non
default one, same problem with hierarchy of exceptions more specified could
occur after general one in tryCatchBlock list.
Maybe best to compare hander indexies?
```https://gitlab.ow2.org/asm/asm/-/issues/317127duplicate entries in InnerClasses attribute2017-12-26T10:12:11Zcushonduplicate entries in InnerClasses attribute```
ASM creates duplicate entries in the InnerClasses attribute of the attached class when it rewrites the
constant pool.
Repro:
$ javac -cp lib/asm-5.0_BETA.jar Test.java
$ java -cp .:lib/asm-5.0_BETA.jar Test weird/JavacWeirdnessTes...```
ASM creates duplicate entries in the InnerClasses attribute of the attached class when it rewrites the
constant pool.
Repro:
$ javac -cp lib/asm-5.0_BETA.jar Test.java
$ java -cp .:lib/asm-5.0_BETA.jar Test weird/JavacWeirdnessTester.class out.class
$ javap -v out.class | head
…
InnerClasses:
static #7 of #2; //class weird/JavacWeirdnessTester$1 of class weird/JavacWeirdnessTester
static #7 of #2; //class weird/JavacWeirdnessTester$1 of class weird/JavacWeirdnessTester
static #7 of #2; //class weird/JavacWeirdnessTester$1 of class weird/JavacWeirdnessTester
The "JavacWeirdnessTester" class comes from a gwt test[1], and was compiled using javac8 -source 7 -
target 7.
[1] https://code.google.com/p/google-web-
toolkit/source/browse/trunk/dev/core/test/com/google/gwt/dev/javac/GeneratedClassnameFinderTest.j
ava
```https://gitlab.ow2.org/asm/asm/-/issues/317532invalidFrames in ClassWriter.toByteArray() causes trouble on older bytecode. ...2017-12-26T10:04:55ZztandresinvalidFrames in ClassWriter.toByteArray() causes trouble on older bytecode. Frames should be ignored?```
Added the reproduction app. Can be run with:
mvn clean package exec:java
It will get exception:
Caused by: java.lang.RuntimeException: JSR/RET are not supported with
computeFrames option
It should not get this exception.
Some olde...```
Added the reproduction app. Can be run with:
mvn clean package exec:java
It will get exception:
Caused by: java.lang.RuntimeException: JSR/RET are not supported with
computeFrames option
It should not get this exception.
Some older javac (java4) and byte code generation libraryes (Jboss4 JSP
compiler for example) generate JSR/RET bytecode instructions and the bytecode
level of those files will be older then Java 6+.
Now if you have a generic method processor that uses the a visitFrame
instruction then this will affect some the state the transformation will fail
on ClassWriter.toByteArray becasue it will re-read the soruce bytecode with
it's own flags and tryes to generate some stackframes althouh this bytecode
does not support it anyway.
I think visitFrame should be ignored on older bytecode transformations.
```https://gitlab.ow2.org/asm/asm/-/issues/317123ASM5.0: Class MethodNode broken?2017-12-26T10:12:21ZmarchofASM5.0: Class MethodNode broken?```
Thanks for releasing ASM 5.0!
Unfortunately it looks like at least one class file in asm-all-5.0.jar is
broken: Using the class MethodNode leads to the following error:
java.lang.ClassFormatError: Repetitive field name/signature in...```
Thanks for releasing ASM 5.0!
Unfortunately it looks like at least one class file in asm-all-5.0.jar is
broken: Using the class MethodNode leads to the following error:
java.lang.ClassFormatError: Repetitive field name/signature in class file
org/objectweb/asm/tree/MethodNode
Indeed if you decompile the class the following field is declared twice:
static java.lang.Class class$org$objectweb$asm$tree$MethodNode;
descriptor: Ljava/lang/Class;
flags: ACC_STATIC
Synthetic: true
The problem didn't exist with ASM 5.0 beta.
```https://gitlab.ow2.org/asm/asm/-/issues/317112Incorrect stackmap generated seems related to switch and Object[][]2017-12-26T10:12:40ZtvlatasIncorrect stackmap generated seems related to switch and Object[][]```
Hi,
We are seeing an invalid stackmap frame being generated and have narrowed down
the reproducer to a fairly simple class along these lines:
import java.math.BigDecimal;
public class SimpObjRet {
public static void main(String...```
Hi,
We are seeing an invalid stackmap frame being generated and have narrowed down
the reproducer to a fairly simple class along these lines:
import java.math.BigDecimal;
public class SimpObjRet {
public static void main(String [] args) {
try {
makeJavaArray(20, 7);
} catch(Exception e) {
e.printStackTrace();
}
}
public static Object[] makeJavaArray(int i, int j) throws Exception {
Object [] obj = null;
switch(j) {
case 7:
obj = new BigDecimal[i];
break;
case 12:
obj = new String[i];
break;
case -2:
obj = new byte[i][];
break;
default:
throw new Exception("failed");
}
return obj;
}
}
Simply reading the class and writing computing the frames is enough to show
this:
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cr.accept(cw, ClassReader.SKIP_FRAMES);
out = cw.toByteArray();
In the resulting class bytes what we see is an initial append frame with an
Opcode.NULL which looks odd, but may not itself be an issue. But at the end of
the method just before the ALOAD we see a full frame which has
a "java/lang/Object" for the local rather than a "[java/lang/Object". That
seems to be the frame that the verifier is unhappy with.
For example:
mv.visitFrame(Opcodes.F_FULL, 3, new Object[] {Opcodes.INTEGER,
Opcodes.INTEGER, "java/lang/Object"}, 0, new Object[] {});
I'm attaching a zip with a reproducer as well. The zip has files from my run
locally (before/after classes), but you can unzip and run it, the "ant"
default should build/run it
thanks
Tony
```https://gitlab.ow2.org/asm/asm/-/issues/317534Modernize ASM code: replace new WrapperType() by autoboxing2017-12-26T10:04:19ZRemi ForaxModernize ASM code: replace new WrapperType() by autoboxing```
ASM source code while being compatible with Java 1.5 doesn't uses autoboxing
feature.
This request was asked by Oracle.
``````
ASM source code while being compatible with Java 1.5 doesn't uses autoboxing
feature.
This request was asked by Oracle.
```https://gitlab.ow2.org/asm/asm/-/issues/317111source debug extension size should not be limeted to 64k2018-01-20T08:38:24Zlauritsource debug extension size should not be limeted to 64k```
cw.visitSource("Test.java", new String(new char[100000]));
Fails with IllegalArgumentException from ByteVector.putUTF8
Probably caused by http://forge.ow2.org/tracker/?
group_id=23&atid=100023&func=detail&aid=316506
``````
cw.visitSource("Test.java", new String(new char[100000]));
Fails with IllegalArgumentException from ByteVector.putUTF8
Probably caused by http://forge.ow2.org/tracker/?
group_id=23&atid=100023&func=detail&aid=316506
```https://gitlab.ow2.org/asm/asm/-/issues/316683Local variables not processed after jump instruction in AnalyzerAdapter2017-12-26T10:13:30ZkammererLocal variables not processed after jump instruction in AnalyzerAdapter```
On visiting jump instruction AnalyzerAdapter resets locals and stack
so after processing "if () {...} else {...}" statement no any local is
processed and maxLocals info not updated:
public void visitJumpInsn(final int opcode, final...```
On visiting jump instruction AnalyzerAdapter resets locals and stack
so after processing "if () {...} else {...}" statement no any local is
processed and maxLocals info not updated:
public void visitJumpInsn(final int opcode, final Label label) {
if (mv != null) {
mv.visitJumpInsn(opcode, label);
}
execute(opcode, 0, null);
if (opcode == Opcodes.GOTO) {
this.locals = null;
this.stack = null;
}
}
NB: Is it any other possibilites to calc maxLocals?
```