]> source.dussan.org Git - javassist.git/commitdiff
Check for extended frame type when updating StackTableOffset offset 351/head
authorSøren Gjesse <sgjesse@google.com>
Mon, 14 Dec 2020 13:52:31 +0000 (14:52 +0100)
committerSøren Gjesse <sgjesse@google.com>
Mon, 14 Dec 2020 13:52:31 +0000 (14:52 +0100)
Fixes #350

src/main/javassist/bytecode/StackMapTable.java
src/test/javassist/bytecode/StackMapTest.java

index 816222008ab6d2b4a3c6f48a896702f7a5159d0d..62a6aca0388ed291158049bdf2e305d983d92a0c 100644 (file)
@@ -204,8 +204,11 @@ public class StackMapTable extends AttributeInfo {
             }
             else if (type < 128)
                 pos = sameLocals(pos, type);
-            else if (type < 247)
-                throw new BadBytecode("bad frame_type in StackMapTable");
+            else if (type < 247) {
+                throw new BadBytecode(
+                    "bad frame_type " + type + " in StackMapTable (pos: "
+                        + pos + ", frame no.:" + nth + ")");
+            }
             else if (type == 247)   // SAME_LOCALS_1_STACK_ITEM_EXTENDED
                 pos = sameLocals(pos, type);
             else if (type < 251) {
@@ -890,11 +893,12 @@ public class StackMapTable extends AttributeInfo {
                 match = oldPos <= where  && where < position;
 
             if (match) {
+                int current = info[pos] & 0xff;
                 int newDelta = offsetDelta + gap;
                 position += gap;
                 if (newDelta < 64)
                     info[pos] = (byte)(newDelta + base);
-                else if (offsetDelta < 64) {
+                else if (offsetDelta < 64 && current != entry) {
                     byte[] newinfo = insertGap(info, pos, 2);
                     newinfo[pos] = (byte)entry;
                     ByteArray.write16bit(newDelta, newinfo, pos + 1);
index 7ea415a97aed7b904acd9f5f9c3942ca11d91513..a0a4f1b194cc2f24f485e339b873dcf322c9740e 100644 (file)
@@ -923,4 +923,81 @@ public class StackMapTest extends TestCase {
         else
             ci.insert(newCode.get());
     }
+
+    public void testIssue350() throws Exception {
+        byte sameLocals1StackItemFrameExtended = 247 - 256;
+        byte sameFrameExtended = 251 - 256;
+        byte appendFrame = 252 - 256;
+        ConstPool cp = new ConstPool("Test");
+        StackMapTable stmt;
+        int originalLength;
+
+        stmt = new StackMapTable(cp, new byte[] {
+            0, 1,
+            sameLocals1StackItemFrameExtended, 0, 63, 1
+        });
+        originalLength = stmt.info.length;
+        assertEquals(63, stmt.info[4]);
+        stmt.shiftPc(0, 2, false);
+        assertEquals(originalLength, stmt.info.length);
+        assertEquals(65, stmt.info[4]);
+
+        stmt = new StackMapTable(cp, new byte[] {
+            0, 1,
+            sameFrameExtended, 0, 63
+        });
+        originalLength = stmt.info.length;
+        assertEquals(63, stmt.info[4]);
+        stmt.shiftPc(0, 2, false);
+        assertEquals(originalLength, stmt.info.length);
+        assertEquals(65, stmt.info[4]);
+
+        stmt = new StackMapTable(cp, new byte[] {
+            0, 2,
+            sameLocals1StackItemFrameExtended, 0, 63, 1,
+            sameFrameExtended, 0, 63
+        });
+        originalLength = stmt.info.length;
+        assertEquals(63, stmt.info[4]);
+        assertEquals(63, stmt.info[8]);
+        stmt.shiftPc(0, 2, false);
+        assertEquals(originalLength, stmt.info.length);
+        assertEquals(65, stmt.info[4]);
+        assertEquals(63, stmt.info[8]);
+        stmt.shiftPc(100, 2, false);
+        assertEquals(65, stmt.info[4]);
+        assertEquals(65, stmt.info[8]);
+
+        // Actual StackMapTable reported in https://github.com/jboss-javassist/javassist/issues/350.
+        stmt = new StackMapTable(cp, new byte[] {
+            0, 7, // size
+            sameLocals1StackItemFrameExtended, 0, 76, 7, 2, 206 - 256,
+            sameLocals1StackItemFrameExtended, 0, 63, 7, 2, 221 - 256,
+            appendFrame, 0, 63, 7, 0, 14,
+            appendFrame, 0, 43, 7, 2, 225 - 256, 1,
+            74, 7, 0, 19,  // same_locals_1_stack_item_frame (not extended)
+            appendFrame, 0, 23, 7, 0, 19,
+            66, 7, 2, 225 - 256 // same_locals_1_stack_item_frame (not extended)
+        });
+        assertEquals(63, stmt.info[10]);
+        originalLength = stmt.info.length;
+
+        stmt.shiftPc(100, 2, false);
+        assertEquals(originalLength, stmt.info.length);
+        assertEquals(65, stmt.info[10]);
+    }
+
+    public static void dump(byte[] content) {
+        final int bytesPerLine = 16;
+        for (int i = 0; i < content.length; i += bytesPerLine) {
+            for (int j = 0; j < bytesPerLine && i + j < content.length; j++) {
+                int unsignedByte = content[i + j];
+                if (unsignedByte < 0) {
+                    unsignedByte = 256 + unsignedByte;
+                }
+                System.out.print(unsignedByte + ", ");
+            }
+            System.out.println();
+        }
+    }
 }