asm issueshttps://gitlab.ow2.org/asm/asm/-/issues2017-12-26T10:41:26Zhttps://gitlab.ow2.org/asm/asm/-/issues/315399AnalyzerAdapter.execute() method doesn't process null array correctly for AAL...2017-12-26T10:41:26Za_glasmanAnalyzerAdapter.execute() method doesn't process null array correctly for AALOAD instruction```
AnalyzerAdapter (visitInsn(Opcodes.AALOAD)) fails on the following valid Java
construction with ClassCastException:
Object[] arr = null;
try {
Object obj = arr[0];
} catch(NullPointerException e) {
// .....```
AnalyzerAdapter (visitInsn(Opcodes.AALOAD)) fails on the following valid Java
construction with ClassCastException:
Object[] arr = null;
try {
Object obj = arr[0];
} catch(NullPointerException e) {
// ...
}
The reason is that AnalyzerAdapter.execute() method consider second stack value
as String for AALOAD instruction:
case Opcodes.AALOAD:
pop(1);
t1 = pop();
pushDesc(((String) t1).substring(1));
break;
However in this case the second value on the stack (array type) will be
Opcodes.NULL which causes ClassCastException.
I'd suggest the following fix for this issue:
case Opcodes.AALOAD:
pop(1);
t1 = pop();
if (t1 instanceof String) {
pushDesc(((String) t1).substring(1));
} else {
push("java/lang/Object");
}
break;
```https://gitlab.ow2.org/asm/asm/-/issues/314481Bug in Remapper related to annotations2018-02-24T09:39:49ZpdevaBug in Remapper related to annotations```
This bug seems to have surfaced in JarJarLinks which uses the asm framework.
It is described in a lot more detail here -
http://code.google.com/p/jarjar/issues/detail?id=21
Basically it seems that the 'Remapping' classes call ren...```
This bug seems to have surfaced in JarJarLinks which uses the asm framework.
It is described in a lot more detail here -
http://code.google.com/p/jarjar/issues/detail?id=21
Basically it seems that the 'Remapping' classes call renamer.mapType(desc) when
they should be calling renamer.mapDesc(desc).
```https://gitlab.ow2.org/asm/asm/-/issues/313997LocalVariablesSorter gets confused when dummy parameters are added to function2017-12-26T10:52:08ZianjoLocalVariablesSorter gets confused when dummy parameters are added to function```
I'm adding a dummy parameter to a method, just as a marker -- it doesn't have
any impact on the code at all, and it remains unchanged. When such a method is
visited by a LocalVariablesSorter, it gets confused and rewrites code wrong....```
I'm adding a dummy parameter to a method, just as a marker -- it doesn't have
any impact on the code at all, and it remains unchanged. When such a method is
visited by a LocalVariablesSorter, it gets confused and rewrites code wrong.
When running the attached example with "java Asmbug" this gets flagged by the
CheckClassAdapter. Running the example with "java Asmbug false" which doesn't
run the code using a LocalVariablesSorter, it checks out ok, and is accepted by
sun's JVM.
This happens both with an older version of asm I was using, and with a recent
svn snapshot.
```https://gitlab.ow2.org/asm/asm/-/issues/312464ClassReader does not ensure that NEW has a label associated with it2017-12-26T10:53:53ZorlovmClassReader does not ensure that NEW has a label associated with it```
This problem occurs in ASM 3.1.
Consider the following test case (inside some class):
public static class RegressionNew {
public static void foo(int x) {
new Integer(x == 0 ? 0 : 1);
}
}
@Test
public void asmRegressionNew() th...```
This problem occurs in ASM 3.1.
Consider the following test case (inside some class):
public static class RegressionNew {
public static void foo(int x) {
new Integer(x == 0 ? 0 : 1);
}
}
@Test
public void asmRegressionNew() throws IOException {
ClassReader cr = new ClassReader(RegressionNew.class.getName());
TraceClassVisitor tcv = new TraceClassVisitor(new PrintWriter(System.out));
cr.accept(tcv, ClassReader.SKIP_DEBUG);
}
I think it doesn't matter which Java compiler is used, but I used Eclipse 3.4.
This results in:
public static foo(I)V
NEW java/lang/Integer
ILOAD 0
IFNE L0
ICONST_0
GOTO L1
L0
FRAME SAME1 L2
ICONST_1
L1
FRAME FULL [I] [L2 I]
INVOKESPECIAL java/lang/Integer.<init> (I)V
RETURN
MAXSTACK = 2
MAXLOCALS = 1
The frame before INVOKESPECIAL is incorrect, since it should contain a label
associated with NEW (it instead contains nonexistent label L2).
The following patch alleviates the problem:
ClassReader, near line 930 ("find the labels" phase):
case ClassWriter.TYPE_INSN:
if (Opcodes.NEW == opcode)
readLabel(w, labels);
case ClassWriter.SHORT_INSN:
case ClassWriter.LDCW_INSN:
case ClassWriter.FIELDORMETH_INSN:
case ClassWriter.IINC_INSN:
v += 3;
break;
Instead of
case ClassWriter.SHORT_INSN:
case ClassWriter.LDCW_INSN:
case ClassWriter.FIELDORMETH_INSN:
case ClassWriter.TYPE_INSN:
case ClassWriter.IINC_INSN:
v += 3;
break;
Now we have:
public static foo(I)V
L0
NEW java/lang/Integer
ILOAD 0
IFNE L1
ICONST_0
GOTO L2
L1
FRAME SAME1 L0
ICONST_1
L2
FRAME FULL [I] [L0 I]
INVOKESPECIAL java/lang/Integer.<init> (I)V
RETURN
MAXSTACK = 2
MAXLOCALS = 1
The frame before INVOKESPECIAL now contains the label L0, which was associated
with NEW. A more precise test case in Jasmin:
.class public RegressionNew
.super java/lang/Object
.method public static foo()V
.limit stack 1
.limit locals 0
new java/lang/Object
goto skip
skip:
invokespecial java/lang/Object/<init>()V
return
.end method
```https://gitlab.ow2.org/asm/asm/-/issues/314086asm 3.2: ClassWriter.COMPUTE_FRAMES causes java.lang.ArrayIndexOutOfBoundsExc...2017-12-26T10:51:27Zronyasm 3.2: ClassWriter.COMPUTE_FRAMES causes java.lang.ArrayIndexOutOfBoundsException```
While trying to take advantage of ClassWriter.COMPUTE_FRAMES, the following
Exception occurs:
------------ cut here ------------
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at org.objectweb.asm.Fra...```
While trying to take advantage of ClassWriter.COMPUTE_FRAMES, the following
Exception occurs:
------------ cut here ------------
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at org.objectweb.asm.Frame.a(Unknown Source)
at org.objectweb.asm.Frame.a(Unknown Source)
at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
at org.objectweb.asm.tree.MethodNode.accept(Unknown Source)
at org.objectweb.asm.util.CheckMethodAdapter$1.visitEnd(Unknown Source)
at org.objectweb.asm.util.CheckMethodAdapter.visitEnd(Unknown Source)
at org.objectweb.asm.util.TraceMethodVisitor.visitEnd(Unknown Source)
at RgfExtendClass.visitMethod(RgfExtendClass.java:447)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at RgfTestCreate.main(RgfTestCreate.java:38)
------------ cut here ------------
Using ClassWirter.COMPUTE_MAXS instead works o.k.
Hence concluding that there is a bug in the respective code. If needed, I could
supply an archive to reproduce this error
```https://gitlab.ow2.org/asm/asm/-/issues/315745JSRInlineAdapter produces duplicate Labels2017-12-26T10:39:02ZmarchJSRInlineAdapter produces duplicate Labels```
Hi,
the JaCoCo code coverage library is currently using the JSRInlineAdapter to
eliminate JSR/RET instructions from classes. The new event sequence produced by
the adapter produces multiple labels in sequence (without intermediate
i...```
Hi,
the JaCoCo code coverage library is currently using the JSRInlineAdapter to
eliminate JSR/RET instructions from classes. The new event sequence produced by
the adapter produces multiple labels in sequence (without intermediate
instructions). For example:
...
L127
LINENUMBER 900 L127
GOTO L113
L130
L119 <-- Two Labels in sequence
ASTORE 19
ALOAD 4
IFNULL L131
...
All other ASM APIs never produce such a situation. Therefore I consider this as
a bug.
STEPS TO REPRODUCE
Pipe the method "isRebuildRequired" from attached class file
WeblogicDeploymentTool.class through an JSRInlineAdapter and dump the result.
EXPECTED BEHAVIOR
There is at most one label preceding each instruction.
ACTUAL BEHAVIOR
The JSRInlineAdapter produces two subsequent labels without instructions in
between.
```https://gitlab.ow2.org/asm/asm/-/issues/314072v 3.2: getElementType() yields an "ArrayIndexOutOfBoundsException"2017-12-26T10:51:41Zronyv 3.2: getElementType() yields an "ArrayIndexOutOfBoundsException"```
Experimenting with "org.objectweb.asm.Type", creating a Type object for an
array, and thereafter trying to get its element type yields the aforementioned
exception.
Something like:
Type t2=Type.getObjectType("[[[java/lang/Byte"...```
Experimenting with "org.objectweb.asm.Type", creating a Type object for an
array, and thereafter trying to get its element type yields the aforementioned
exception.
Something like:
Type t2=Type.getObjectType("[[[java/lang/Byte");
System.out.println("t2.getDimensions()="+t2.getDimensions());
System.out.println("t2.getElementType()="+t2.getElementType());
will yield the following output:
E:\rony\dev\bsf\src\source_cc_40\extendJava\dev>java TestType
t2.getDimensions()=3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 17
at org.objectweb.asm.Type.a(Unknown Source)
at org.objectweb.asm.Type.getElementType(Unknown Source)
at TestType.main(TestType.java:12)
---rony, 2009-07-23
```https://gitlab.ow2.org/asm/asm/-/issues/316050Invalid conversion of non-BMP characters to UTF82017-12-26T10:36:06ZmhkayInvalid conversion of non-BMP characters to UTF8```
When a string containing non-BMP characters is written to the constant pool, the
conversion to UTF-8 is done incorrectly, resulting in a failure to load the
generated class (ClassFormatError: Illegal UTF-8 string in constant pool)....```
When a string containing non-BMP characters is written to the constant pool, the
conversion to UTF-8 is done incorrectly, resulting in a failure to load the
generated class (ClassFormatError: Illegal UTF-8 string in constant pool).
The method ByteVector.putUTF8() makes no attempt to recognize surrogate pairs in
the supplied string, but instead converts each of the two surrogates separately.
To quote from the Unicode FAQ (http://unicode.org/faq/utf_bom.html#utf8-4),
"The definition of UTF-8 requires that supplementary characters (those using
surrogate pairs in UTF-16) be encoded with a single four byte sequence. However,
there is a widespread practice of generating pairs of three byte sequences in
older software, especially software which pre-dates the introduction of UTF-16
or that is interoperating with UTF-16 environments under particular constraints.
Such an encoding is not conformant to UTF-8 as defined."
```https://gitlab.ow2.org/asm/asm/-/issues/316048ClassFormatError: Illegal exception table range when generating class2017-12-26T10:36:34ZianjoClassFormatError: Illegal exception table range when generating class```
In the middle of doing a complex transformation of a class, I actually end up
with no code between two labels, which are used in a TryCatchBlock (so the
block goes unused).
The ClassWriter correctly detects the TryCatchBlock is empt...```
In the middle of doing a complex transformation of a class, I actually end up
with no code between two labels, which are used in a TryCatchBlock (so the
block goes unused).
The ClassWriter correctly detects the TryCatchBlock is empty and replaces with
the NOP/ATHROW stuff, but it does not remove the entry from the exception
table, resulting in an error when the class is loaded by Java.
The following example demonstrates this:
import java.io.*;
import org.objectweb.asm.*;
public class AsmTryCatchBlockTestcase implements Opcodes {
public static void main(String[] args) throws Exception {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_6, ACC_PUBLIC, "TryCatchIssue", null, "java/lang/Object", null);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC|ACC_STATIC, "m", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitInsn(RETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitInsn(RETURN);
mv.visitTryCatchBlock(l0, l1, l2, null);
mv.visitMaxs(0, 0);
mv.visitEnd();
cw.visitEnd();
FileOutputStream fos = new FileOutputStream("TryCatchIssue.class");
fos.write(cw.toByteArray());
fos.close();
}
}
java TryCatchIssue then results in
$ java TryCatchIssue
Exception in thread "main" java.lang.ClassFormatError: Illegal exception table
range in class file TryCatchIssue
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: TryCatchIssue. Program will exit.
I do know that I can fix this (and indeed I do it) in my code by re-processing
the class to fix the exception table, but I believe that this would more
correctly be done inside ClassWriter, when the block is detected to be
unreachable code.
Thanks.
```https://gitlab.ow2.org/asm/asm/-/issues/313909VOID_TYPE.getSize() != 02017-12-26T10:52:26ZseweVOID_TYPE.getSize() != 0```
While this behavior is documented as ("2 for long and double, and 1
otherwise."), it not only seems unintuitive but also time and again requires
code for the special case of VOID_TYPE. :-(
``````
While this behavior is documented as ("2 for long and double, and 1
otherwise."), it not only seems unintuitive but also time and again requires
code for the special case of VOID_TYPE. :-(
```https://gitlab.ow2.org/asm/asm/-/issues/315697DependencyTracker example fails in handling class Object2017-12-26T10:40:05ZeryDependencyTracker example fails in handling class Object```
The example application DependencyTracker fails (null pointer exception) if
input includes the class Object. This happens when analyzing dependencies in
platform libraries that include the Object.class.
The bug is in method visit ...```
The example application DependencyTracker fails (null pointer exception) if
input includes the class Object. This happens when analyzing dependencies in
platform libraries that include the Object.class.
The bug is in method visit in DependencyVisitor.java as follows:
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces)
{
String p = getGroupKey(name);
current = groups.get(p);
if (current == null) {
current = new HashMap<String, Integer>();
groups.put(p, current);
}
if (signature == null) {
addInternalName(superName); // BUG: superName is null for Object
addInternalNames(interfaces);
} else {
addSignature(signature);
}
}
Correction proposal:
public void visit(
final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces)
{
String p = getGroupKey(name);
current = groups.get(p);
if (current == null) {
current = new HashMap<String, Integer>();
groups.put(p, current);
}
if (signature == null) {
if (superName != null) // Class Object has no super class
addInternalName(superName);
addInternalNames(interfaces);
} else {
addSignature(signature);
}
}
```https://gitlab.ow2.org/asm/asm/-/issues/315699Use the variable arguments list in Type.getMethodDescriptor instead of an arr...2017-12-26T10:39:17ZfoobarUse the variable arguments list in Type.getMethodDescriptor instead of an array of Type```
Hi
If ASM is running with a JRE greater or equal to the 1.5, it would be usefull
to change the signature of the Type.getMethodDescriptor to
String getMethodDescriptor(Type returnType, Type... argumentTypes)
that avoids creating i...```
Hi
If ASM is running with a JRE greater or equal to the 1.5, it would be usefull
to change the signature of the Type.getMethodDescriptor to
String getMethodDescriptor(Type returnType, Type... argumentTypes)
that avoids creating in the source an array of Type.
Rgds
foobar
```https://gitlab.ow2.org/asm/asm/-/issues/315698DependencyTracker example fails in handling finally blocks2017-12-26T10:39:48ZeryDependencyTracker example fails in handling finally blocks```
The example application DependencyTracker fails (null pointer exception) if
input includes finally blocks (of the try-catch-finally programming structure).
The bug might be in method visitTryCatchBlock in DependencyVisitor.java as ...```
The example application DependencyTracker fails (null pointer exception) if
input includes finally blocks (of the try-catch-finally programming structure).
The bug might be in method visitTryCatchBlock in DependencyVisitor.java as
follows:
public void visitTryCatchBlock(
final Label start,
final Label end,
final Label handler,
final String type)
{
addInternalName(type);
}
It seems that if the analyzed code includes a finally block, this method gets
called without a type and calling addInternalName with null ends up all wrong
eventually.
I am not sure if this is the right place to correct the bug, but I did this to
get rid of the problem:
public void visitTryCatchBlock(
final Label start,
final Label end,
final Label handler,
final String type)
{
// Condition added to deal with finally blocks (type == null).
if (type != null)
addInternalName(type);
}
```https://gitlab.ow2.org/asm/asm/-/issues/316212org.objectweb.asm.optimizer.ClassOptimizer does not work with classes in defa...2017-12-12T06:25:41Zpicpromusicorg.objectweb.asm.optimizer.ClassOptimizer does not work with classes in default package```
The line
pkgName = name.substring(0, name.lastIndexOf('/'));
in ClassOptimizer.visit(...) causes an StringArrayOutOfBoundsException when a
class of the default package is passed to the org.objectweb.asm.optimizer.Shrinker.
...```
The line
pkgName = name.substring(0, name.lastIndexOf('/'));
in ClassOptimizer.visit(...) causes an StringArrayOutOfBoundsException when a
class of the default package is passed to the org.objectweb.asm.optimizer.Shrinker.
```https://gitlab.ow2.org/asm/asm/-/issues/316027ClassReader leaks file descriptors2017-12-26T10:36:54ZysibataClassReader leaks file descriptors```
ClassReader class in the org.objectweb.asm package doesn't close input streams.
/**
* Constructs a new {@link ClassReader} object.
*
* @param name the binary qualified name of the class to be read.
* @throws ...```
ClassReader class in the org.objectweb.asm package doesn't close input streams.
/**
* Constructs a new {@link ClassReader} object.
*
* @param name the binary qualified name of the class to be read.
* @throws IOException if an exception occurs during reading.
*/
public ClassReader(final String name) throws IOException {
this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+ ".class"));
}
If you use this constructor, any InputStream returned by
ClassLoader.getSystemResourceAsStream() will never be closed properly.
Eventually we will run out of file descriptors on the system.
Regards,
Yoshiki Shibata
```https://gitlab.ow2.org/asm/asm/-/issues/315248Bug in CheckClassAdapter? Fails for untransformed class2018-09-03T18:19:09ZjoneianBug in CheckClassAdapter? Fails for untransformed class```
Hi,
I'm using ASM for a project, and am very impressed - really nice to use. I'm a
bit of a novice using ASM so not sure if I have found a bug, or doing something
wrong, but I found behaviour that I found odd.
I was trying to te...```
Hi,
I'm using ASM for a project, and am very impressed - really nice to use. I'm a
bit of a novice using ASM so not sure if I have found a bug, or doing something
wrong, but I found behaviour that I found odd.
I was trying to test my instrumentation by letting it transform every class
loaded by the JVM and came across a class untouched by my instrumentation, but
failed in the CheckClassAdapter. Upon further investigation I found it was
repeatable.
Below is my test case and output. I'm using ASM 3.3, and Sun JDK 1.6.0_05.
Cheers,
Ian
@Test
public void testCheckAdapter() throws Exception {
InputStream classStream =
this.getClass().getClassLoader().getResourceAsStream(SunRsaSign.class.getName()
.replace('.', '/') + ".class");
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(out, true);
CheckClassAdapter.verify(new ClassReader(classStream), false,
pw);
if(out.size() > 0) {
Assert.fail("Should not fail as as haven't done any
transformation from original class. Error is: " + out.toString());
}
}
Which gives the output:
java.lang.AssertionError: Should not fail as as haven't done any transformation
from original class. Error is:
org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 18:
Method owner: expected Ljava/util/Map;, but found Ljava/lang/Object;
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:291)
at
org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:224)
at
org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:250)
at com.iandjones.canal.ASMTest.testCheckAdapter(ASMTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.jav
a:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java
:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:2
0)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:7
3)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:4
6)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRefere
nce.java:46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.jav
a:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.ja
va:197)
Caused by: org.objectweb.asm.tree.analysis.AnalyzerException: Method owner:
expected Ljava/util/Map;, but found Ljava/lang/Object;
at
org.objectweb.asm.tree.analysis.BasicVerifier.naryOperation(BasicVerifier.java:
395)
at org.objectweb.asm.tree.analysis.Frame.execute(Frame.java:593)
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:192)
... 27 more
<init>()V
00000 SunRsaSign . . : : ALOAD 0
00001 SunRsaSign . . : SunRsaSign : LDC "SunRsaSign"
00002 SunRsaSign . . : SunRsaSign String : LDC 1.5
00003 SunRsaSign . . : SunRsaSign String D : LDC "Sun RSA signature
provider"
00004 SunRsaSign . . : SunRsaSign String D String : INVOKESPECIAL
java/security/Provider.<init> (Ljava/lang/String;DLjava/lang/String;)V
00005 SunRsaSign . . : : INVOKESTATIC java/lang/System.getSecurityManager
()Ljava/lang/SecurityManager;
00006 SunRsaSign . . : SecurityManager : IFNONNULL L0
00007 SunRsaSign . . : : ALOAD 0
00008 SunRsaSign . . : SunRsaSign : GOTO L1
00009 SunRsaSign . . : : L0
00010 SunRsaSign . . : : NEW java/util/HashMap
00011 SunRsaSign . . : HashMap : DUP
00012 SunRsaSign . . : HashMap HashMap : INVOKESPECIAL
java/util/HashMap.<init> ()V
00013 SunRsaSign . . : Object : L1
00014 SunRsaSign . . : Object : ASTORE 1
00015 SunRsaSign Object . : : ALOAD 1
00016 SunRsaSign Object . : Object : LDC "KeyFactory.RSA"
00017 SunRsaSign Object . : Object String : LDC
"sun.security.rsa.RSAKeyFactory"
00018 SunRsaSign Object . : Object String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00019 SunRsaSign HashMap . : Object : POP
00020 SunRsaSign HashMap . : : ALOAD 1
00021 SunRsaSign HashMap . : HashMap : LDC "KeyPairGenerator.RSA"
00022 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSAKeyPairGenerator"
00023 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00024 SunRsaSign HashMap . : Object : POP
00025 SunRsaSign HashMap . : : ALOAD 1
00026 SunRsaSign HashMap . : HashMap : LDC "Signature.MD2withRSA"
00027 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$MD2withRSA"
00028 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00029 SunRsaSign HashMap . : Object : POP
00030 SunRsaSign HashMap . : : ALOAD 1
00031 SunRsaSign HashMap . : HashMap : LDC "Signature.MD5withRSA"
00032 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$MD5withRSA"
00033 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00034 SunRsaSign HashMap . : Object : POP
00035 SunRsaSign HashMap . : : ALOAD 1
00036 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA1withRSA"
00037 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA1withRSA"
00038 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00039 SunRsaSign HashMap . : Object : POP
00040 SunRsaSign HashMap . : : ALOAD 1
00041 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA256withRSA"
00042 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA256withRSA"
00043 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00044 SunRsaSign HashMap . : Object : POP
00045 SunRsaSign HashMap . : : ALOAD 1
00046 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA384withRSA"
00047 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA384withRSA"
00048 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00049 SunRsaSign HashMap . : Object : POP
00050 SunRsaSign HashMap . : : ALOAD 1
00051 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA512withRSA"
00052 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA512withRSA"
00053 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00054 SunRsaSign HashMap . : Object : POP
00055 SunRsaSign HashMap . : : LDC
"java.security.interfaces.RSAPublicKey|java.security.interfaces.RSAPrivateKey"
00056 SunRsaSign HashMap . : String : ASTORE 2
00057 SunRsaSign HashMap String : : ALOAD 1
00058 SunRsaSign HashMap String : HashMap : LDC "Signature.MD2withRSA
SupportedKeyClasses"
00059 SunRsaSign HashMap String : HashMap String : ALOAD 2
00060 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00061 SunRsaSign HashMap String : Object : POP
00062 SunRsaSign HashMap String : : ALOAD 1
00063 SunRsaSign HashMap String : HashMap : LDC "Signature.MD5withRSA
SupportedKeyClasses"
00064 SunRsaSign HashMap String : HashMap String : ALOAD 2
00065 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00066 SunRsaSign HashMap String : Object : POP
00067 SunRsaSign HashMap String : : ALOAD 1
00068 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA1withRSA
SupportedKeyClasses"
00069 SunRsaSign HashMap String : HashMap String : ALOAD 2
00070 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00071 SunRsaSign HashMap String : Object : POP
00072 SunRsaSign HashMap String : : ALOAD 1
00073 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA256withRSA
SupportedKeyClasses"
00074 SunRsaSign HashMap String : HashMap String : ALOAD 2
00075 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00076 SunRsaSign HashMap String : Object : POP
00077 SunRsaSign HashMap String : : ALOAD 1
00078 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA384withRSA
SupportedKeyClasses"
00079 SunRsaSign HashMap String : HashMap String : ALOAD 2
00080 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00081 SunRsaSign HashMap String : Object : POP
00082 SunRsaSign HashMap String : : ALOAD 1
00083 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA512withRSA
SupportedKeyClasses"
00084 SunRsaSign HashMap String : HashMap String : ALOAD 2
00085 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00086 SunRsaSign HashMap String : Object : POP
00087 SunRsaSign HashMap String : : ALOAD 1
00088 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyFactory.1.2.840.113549.1.1"
00089 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00090 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00091 SunRsaSign HashMap String : Object : POP
00092 SunRsaSign HashMap String : : ALOAD 1
00093 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1"
00094 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00095 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00096 SunRsaSign HashMap String : Object : POP
00097 SunRsaSign HashMap String : : ALOAD 1
00098 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1"
00099 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00100 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00101 SunRsaSign HashMap String : Object : POP
00102 SunRsaSign HashMap String : : ALOAD 1
00103 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1"
00104 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00105 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00106 SunRsaSign HashMap String : Object : POP
00107 SunRsaSign HashMap String : : ALOAD 1
00108 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.2"
00109 SunRsaSign HashMap String : HashMap String : LDC "MD2withRSA"
00110 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00111 SunRsaSign HashMap String : Object : POP
00112 SunRsaSign HashMap String : : ALOAD 1
00113 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.2"
00114 SunRsaSign HashMap String : HashMap String : LDC "MD2withRSA"
00115 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00116 SunRsaSign HashMap String : Object : POP
00117 SunRsaSign HashMap String : : ALOAD 1
00118 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.4"
00119 SunRsaSign HashMap String : HashMap String : LDC "MD5withRSA"
00120 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00121 SunRsaSign HashMap String : Object : POP
00122 SunRsaSign HashMap String : : ALOAD 1
00123 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.4"
00124 SunRsaSign HashMap String : HashMap String : LDC "MD5withRSA"
00125 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00126 SunRsaSign HashMap String : Object : POP
00127 SunRsaSign HashMap String : : ALOAD 1
00128 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.5"
00129 SunRsaSign HashMap String : HashMap String : LDC "SHA1withRSA"
00130 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00131 SunRsaSign HashMap String : Object : POP
00132 SunRsaSign HashMap String : : ALOAD 1
00133 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.5"
00134 SunRsaSign HashMap String : HashMap String : LDC "SHA1withRSA"
00135 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00136 SunRsaSign HashMap String : Object : POP
00137 SunRsaSign HashMap String : : ALOAD 1
00138 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.3.14.3.2.29"
00139 SunRsaSign HashMap String : HashMap String : LDC "SHA1withRSA"
00140 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00141 SunRsaSign HashMap String : Object : POP
00142 SunRsaSign HashMap String : : ALOAD 1
00143 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.11"
00144 SunRsaSign HashMap String : HashMap String : LDC "SHA256withRSA"
00145 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00146 SunRsaSign HashMap String : Object : POP
00147 SunRsaSign HashMap String : : ALOAD 1
00148 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.11"
00149 SunRsaSign HashMap String : HashMap String : LDC "SHA256withRSA"
00150 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00151 SunRsaSign HashMap String : Object : POP
00152 SunRsaSign HashMap String : : ALOAD 1
00153 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.12"
00154 SunRsaSign HashMap String : HashMap String : LDC "SHA384withRSA"
00155 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00156 SunRsaSign HashMap String : Object : POP
00157 SunRsaSign HashMap String : : ALOAD 1
00158 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.12"
00159 SunRsaSign HashMap String : HashMap String : LDC "SHA384withRSA"
00160 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00161 SunRsaSign HashMap String : Object : POP
00162 SunRsaSign HashMap String : : ALOAD 1
00163 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.13"
00164 SunRsaSign HashMap String : HashMap String : LDC "SHA512withRSA"
00165 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00166 SunRsaSign HashMap String : Object : POP
00167 SunRsaSign HashMap String : : ALOAD 1
00168 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.13"
00169 SunRsaSign HashMap String : HashMap String : LDC "SHA512withRSA"
00170 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00171 SunRsaSign HashMap String : Object : POP
00172 SunRsaSign HashMap String : : ALOAD 1
00173 SunRsaSign HashMap String : HashMap : ALOAD 0
00174 SunRsaSign HashMap String : HashMap SunRsaSign : IF_ACMPEQ L2
00175 SunRsaSign HashMap String : : NEW sun/security/action/PutAllAction
00176 SunRsaSign HashMap String : PutAllAction : DUP
00177 SunRsaSign HashMap String : PutAllAction PutAllAction : ALOAD 0
00178 SunRsaSign HashMap String : PutAllAction PutAllAction SunRsaSign :
ALOAD 1
00179 SunRsaSign HashMap String : PutAllAction PutAllAction SunRsaSign HashMap
: INVOKESPECIAL sun/security/action/PutAllAction.<init>
(Ljava/security/Provider;Ljava/util/Map;)V
00180 SunRsaSign HashMap String : PutAllAction : INVOKESTATIC
java/security/AccessController.doPrivileged
(Ljava/security/PrivilegedAction;)Ljava/lang/Object;
00181 SunRsaSign HashMap String : Object : POP
00182 SunRsaSign HashMap String : : L2
00183 SunRsaSign HashMap String : : RETURN
at org.junit.Assert.fail(Assert.java:91)
at com.iandjones.canal.ASMTest.testCheckAdapter(ASMTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.jav
a:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java
:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:2
0)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:7
3)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:4
6)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRefere
nce.java:46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.jav
a:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.ja
va:197)
```https://gitlab.ow2.org/asm/asm/-/issues/313314ClassReader.readClass(InputStream) unnecessary copies read buffer two times2017-12-26T10:53:14ZktauberClassReader.readClass(InputStream) unnecessary copies read buffer two times```
ClassReader.readClass(InputStream) unnecessary copies the read buffer two times
when reading a class. First it creates a buffer using is.available(), then it
increases the buffer size by 1000 bytes and then decreases the buffer size ...```
ClassReader.readClass(InputStream) unnecessary copies the read buffer two times
when reading a class. First it creates a buffer using is.available(), then it
increases the buffer size by 1000 bytes and then decreases the buffer size by
1000 bytes. So if a class file is 20000 bytes large, readClass() creates three
buffers of size 20000, 21000 and 20000, which is unnecessary.
This happens always when is.available() returns the complete size of the class
file.
To avoid this, I suggest to try to read one byte if (len == b.length) and
return the initial buffer on EOF.
In ClassReader.java at line 397 change the existing "if" block to:
if (len == b.length) {
int last = is.read();
if( last < 0 )
return b;
byte[] c = new byte[b.length + 1000];
System.arraycopy(b, 0, c, 0, len);
b = c;
b[len++] = (byte) last;
}
```https://gitlab.ow2.org/asm/asm/-/issues/312468Incorrect merging of frames2018-01-20T10:57:49ZorlovmIncorrect merging of frames```
Consider the following Jasmin code:
.class public SimpleDecoherence
.super java/lang/Object
.method public static foo(J)V
.limit stack 1
.limit locals 2
iconst_0
ifne skip
iconst_0
istore_1
skip:
re...```
Consider the following Jasmin code:
.class public SimpleDecoherence
.super java/lang/Object
.method public static foo(J)V
.limit stack 1
.limit locals 2
iconst_0
ifne skip
iconst_0
istore_1
skip:
return
.end method
The following test case (using ASM 3.1) reads the compiled class, writes it
with COMPUTE_FRAMES, rereads and prints.
ClassReader cr = new ClassReader("SimpleDecoherence");
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cr.accept(cw, 0);
ClassReader cr2 = new ClassReader(cw.toByteArray());
TraceClassVisitor tcv = new TraceClassVisitor(new PrintWriter(System.out));
cr2.accept(tcv, 0);
Here is the result:
public static foo(J)V
FRAME FULL [] []
ICONST_0
IFNE L0
ICONST_0
ISTORE 1
L0
FRAME FULL [J] []
RETURN
MAXSTACK = 1
MAXLOCALS = 2
In the second FRAME, the parameter is still "J T", while it should be "T T". I
tried to fix this as follows in org.objectweb.asm.Frame (near line 930, the
third t2 compairson):
case Opcodes.ISTORE:
case Opcodes.FSTORE:
case Opcodes.ASTORE:
t1 = pop();
set(arg, t1);
if (arg > 0) {
t2 = get(arg - 1);
// if t2 is of kind STACK or LOCAL we cannot know its size!
if (t2 == LONG || t2 == DOUBLE || t2 == (LOCAL | 0)) {
set(arg - 1, TOP);
}
}
break;
and similar for LSTORE/DSTORE. The result is now:
public static foo(J)V
FRAME FULL [] []
ICONST_0
IFNE L0
ICONST_0
ISTORE 1
L0
FRAME FULL [] []
RETURN
MAXSTACK = 1
MAXLOCALS = 2
However, changing descriptor of foo to (I)V results in variable 0 turned to T
as well. I guess that's why the comment about not knowing the size is there.
Unfortunately, I am not sufficiently familiar with the implementation to
provide a real fix... (Don't really understand why t2 isn't just LONG there.)
NOTE: technically, the code (after COMPUTE_FRAMES) passes verification, but an
incorrect frame is still a problem for code that analyzes frames.
```https://gitlab.ow2.org/asm/asm/-/issues/316204Analyzer produces incorrect lvt types for jsr return targets when jsr frame c...2017-12-26T09:12:31ZkhoffmanAnalyzer produces incorrect lvt types for jsr return targets when jsr frame changes twice during analysis```
I'm using ASM to perform some analyses that are very sensitive to type
information in the local variable table. Tracking down a problem with the
results of one of the analyses led me to find a rare bug in ASM.
The bug happens when r...```
I'm using ASM to perform some analyses that are very sensitive to type
information in the local variable table. Tracking down a problem with the
results of one of the analyses led me to find a rare bug in ASM.
The bug happens when running BasicInterpreter (and thus Analyzer) on the class
org.eclipse.core.runtime.internal.adaptor.BundleStopper. The problem happens
when you have a JSR instruction that can be reached from two different control
flow paths, one path with more active LVT variables than the other path.
Consider the following (a simplification of the problematic code from
BundleStopper.basicStopBundles()):
for (...) {
try {
Object o1 = new Object();
} catch (Exception e) {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
} finally {
System.out.println("hi");
}
}
This gets compiled such that the end of the try block and the end of the catch
block both JUMP to a label and then immediately executes a JSR to the finally
block (the compiler also could have put a separate JSR at the end of each
block, which would have avoided the bug, but for whatever reason, it chose to
JUMP at the end of each block and then do the JSR).
Now consider what happens if Analyzer happens to process the catch block in the
queue before the try block. The catch block uses more LVT slots, and so when it
JUMPs to the label right before the JSR, initially that label will be populated
with type information for all of those LVT slots.
Then let's say that the JSR subroutine happens to be processed next in the
queue. At the end of the JSR when it reaches the RET instruction, it will merge
its current frame at the end of the JSR (except for variables accessed in the
JSR) with the frame of the calling instruction and merge that with the return
target (the instruction following the JSR instruction). At this point the
calling JSR instruction still have a state with the extra LVT variables, and so
it propagates this to the next instruction (the return target, happens to be a
label).
Eventually the queue contains the if block and at the end of the if block we
merge our LVT state with the JUMP target, which reduces the number of valid LVT
slots at the JSR instruction. The JSR instruction gets processed again, but
there are no changes to be merged (the subroutine by this point already had the
LVT slots that were fewer), and so the analysis terminates.
However, this leaves the return target of the JSR instruction (the instruction
after the JSR instruction) with an LVT that has too be many variables in it.
The key insight to fixing this is to realize that anytime the LVT of a JSR
instruction changes, we must add to the queue the RET instructions of the
relevant subroutine.
I have implemented this in the attached patch, and verified that it works
correctly. The patch uses a map to track the RET instruction(s) that jump to
any JSR return target that have already been processed. When a JSR is processed
in the queue, it always adds these RET instructions into the queue as well
(even if no changes were caused by the JSR instruction itself, if we are
processing the JSR instruction something caused the JSR instruction's state
itself to change, so we just propagate this one step further).
I will be attaching the printout of the LVT/STACK of the actual
BundleStopper.basicStopBundles method anaylsis before the fix and after the
fix, as well as the patch against SVN /tags/ASM_3_3_2 release. I'm also
attaching the .jar file with the .class file that will reproduce the problem.
I also fixed another problem along the way with this patch -- if there are
multiple callers for the same subroutine then the code to add another caller to
the subroutine doesn't update all of the copies of the subroutine in the
subroutines array (because findSubroutine makes a deep copy of the subroutine
for each entry). The fix is to update all of the subroutines entries when a
second caller is added to a subroutine object.
```https://gitlab.ow2.org/asm/asm/-/issues/315984asm-xml.dtd fails to mention FREM element2017-12-26T09:15:34Zseweasm-xml.dtd fails to mention FREM element```
This bug is related to #315942. The DTD and the code are out-of-sync.
``````
This bug is related to #315942. The DTD and the code are out-of-sync.
```