From 4d61dd15f14f0dc17dd990580fcbc793533c51e9 Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Sun, 18 Feb 2018 11:17:19 +0100 Subject: [PATCH 1/3] Revert bug fix. --- .../objectweb/asm/commons/LocalVariablesSorter.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java index dbaecdbb..dadeca2e 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java @@ -65,6 +65,8 @@ public class LocalVariablesSorter extends MethodVisitor { /** Index of the next local variable to be created by {@link #newLocal}. */ protected int nextLocal; + private boolean changed; + /** * Constructs a new {@link LocalVariablesSorter}. Subclasses must not use this constructor. * Instead, they must use the {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} @@ -186,6 +188,10 @@ public class LocalVariablesSorter extends MethodVisitor { throw new IllegalStateException( "ClassReader.accept() should be called with EXPAND_FRAMES flag"); } + if (!changed) { // optimization for the case where mapping = identity + mv.visitFrame(type, nLocal, local, nStack, stack); + return; + } // creates a copy of newLocals Object[] oldLocals = new Object[newLocals.length]; @@ -281,6 +287,7 @@ public class LocalVariablesSorter extends MethodVisitor { int local = newLocalMapping(type); setLocalType(local, type); setFrameLocal(local, t); + changed = true; return local; } @@ -338,6 +345,9 @@ public class LocalVariablesSorter extends MethodVisitor { } else { value--; } + if (value != var) { + changed = true; + } return value; } -- GitLab From e8e78f19a888c81430fd1477cd6a3fa2f1c06aaa Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Sun, 18 Feb 2018 11:17:37 +0100 Subject: [PATCH 2/3] Add failing test showing the issue. --- .../asm/commons/LocalVariablesSorterTest.java | 28 ++++++++++++++++++ .../src/test/resources/Issue317586.class | Bin 0 -> 1112 bytes 2 files changed, 28 insertions(+) create mode 100644 asm-commons/src/test/resources/Issue317586.class diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java index adf47b97..0d4d81fc 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java @@ -30,12 +30,18 @@ package org.objectweb.asm.commons; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.objectweb.asm.test.Assertions.assertThat; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import org.objectweb.asm.test.AsmTest; /** @@ -77,4 +83,26 @@ public class LocalVariablesSorterTest extends AsmTest { .succeedsOrThrows(UnsupportedClassVersionError.class) .when(classParameter.isMoreRecentThanCurrentJdk()); } + + @Test + public void testSortLocalVariablesAndInstantiate() throws FileNotFoundException, IOException { + ClassReader classReader = + new ClassReader(new FileInputStream("src/test/resources/Issue317586.class")); + ClassWriter classWriter = new ClassWriter(0); + ClassVisitor classVisitor = + new ClassVisitor(Opcodes.ASM6, classWriter) { + @Override + public MethodVisitor visitMethod( + final int access, + final String name, + final String desc, + final String signature, + final String[] exceptions) { + return new LocalVariablesSorter( + api, access, desc, super.visitMethod(access, name, desc, signature, exceptions)); + } + }; + classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES); + loadAndInstantiate("app1.Main$BadLocal", classWriter.toByteArray()); + } } diff --git a/asm-commons/src/test/resources/Issue317586.class b/asm-commons/src/test/resources/Issue317586.class new file mode 100644 index 0000000000000000000000000000000000000000..32af483eec1d7d0a6aa866398ffb945a5f741cc5 GIT binary patch literal 1112 zcmZ`&TTc^F5dKatY`ZQ3g<=s!P}G(!)Ivc8ya3UpNsEakAdgFXfW@-iY+L0I8J>9o zBZ<68;;->lAH?r$xo8@b-JO{;m+zZ7v)_Mz`3fM1ml^^BG0SzcnWAMoql;FhP%B$i z4IzQ<9qWUYsanof=FP^AEH?x?=55DrJQoNiQ>y}@rCLSm2qJ1Aj1GaWg6+uV=I(~{ zR;-PxWO2XVs^!_rK0gdKw(Yt=U!fg&jv#ew*HyXttG%*x8+Og9Yv>W^y&`n!(ap>TX0f@sDLq+vE3Jz3G{gyV;VU&f+u3S)BDf(C$?B8(l%CUd^kG1Ca8n?jEL@?q zQsz>tI%2q`B5sq#c?98F#eDxAjA$4Z=()#`z{_`BK5VD`gHPz|rW zevH2LSpN|cM;Kh*hY_3!4}?BrXl?uuqwBMw)3YDr-(b>8?qjq-T~oSwQZ!EyNf-9f zX{J9RVx|vankNTDjKjo?kGg;b${-ZeA-|0*y;Df=*B!((MyQ*3j5R#*JIIk8xt(_q z=Xzu@$@~POjLfl*B(0V<$nK_z6J|bGC342Fum+(a?LRS%Rq+dv6`B+a6w&BUjv|0r RrUWpDc}krp0?+UQkw5dp?RWqH literal 0 HcmV?d00001 -- GitLab From c27d984b7bb6d29937fab435fc133c8ec31884af Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Sun, 18 Feb 2018 11:18:09 +0100 Subject: [PATCH 3/3] Restore bug fix, make previously added test pass. --- .../objectweb/asm/commons/LocalVariablesSorter.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java index dadeca2e..dbaecdbb 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java @@ -65,8 +65,6 @@ public class LocalVariablesSorter extends MethodVisitor { /** Index of the next local variable to be created by {@link #newLocal}. */ protected int nextLocal; - private boolean changed; - /** * Constructs a new {@link LocalVariablesSorter}. Subclasses must not use this constructor. * Instead, they must use the {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} @@ -188,10 +186,6 @@ public class LocalVariablesSorter extends MethodVisitor { throw new IllegalStateException( "ClassReader.accept() should be called with EXPAND_FRAMES flag"); } - if (!changed) { // optimization for the case where mapping = identity - mv.visitFrame(type, nLocal, local, nStack, stack); - return; - } // creates a copy of newLocals Object[] oldLocals = new Object[newLocals.length]; @@ -287,7 +281,6 @@ public class LocalVariablesSorter extends MethodVisitor { int local = newLocalMapping(type); setLocalType(local, type); setFrameLocal(local, t); - changed = true; return local; } @@ -345,9 +338,6 @@ public class LocalVariablesSorter extends MethodVisitor { } else { value--; } - if (value != var) { - changed = true; - } return value; } -- GitLab