Menu

#664 Proguard corrupts stack map frames

v5.3.3
closed-fixed
nobody
None
High
2019-12-06
2017-09-08
No

After proguarding next code java fails with VerificationError

package test

import java.io.File

fun File.descendantRelativeTo(base: File): File {
    val prefix = base.canonicalPath
    val answer = this.canonicalPath
    return if (answer.startsWith(prefix)) {
        val prefixSize = prefix.length
        if (answer.length > prefixSize) {
            File(answer.substring(prefixSize + 1))
        } else File("")
    } else {
        this
    }
}

fun main(args: Array<String>) {
    File("/test").descendantRelativeTo(File("/test"))
}

Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 105
Exception Details:
Location:
test/FileUtilsKt.main([Ljava/lang/String;)V @105: iload_0
Reason:
Type uninitialized 78 (current frame, locals[2]) is not assignable to 'java/io/File' (stack map, locals[2])
Current Frame:
bci: @92
flags: { }
locals: { integer, 'java/lang/String', uninitialized 78, uninitialized 78 }
stack: { 'java/lang/String', 'java/lang/String' }
Stackmap Frame:
bci: @105
flags: { }
locals: { integer, top, 'java/io/File', 'java/io/File' }
stack: { 'java/lang/String' }
Bytecode:
0x0000000: 2a12 05b8 0017 bb00 0a59 1204 b700 11bb
0x0000010: 000a 5912 04b7 0011 4c59 4b12 02b8 0017
0x0000020: 2b12 06b8 0017 2bb6 0012 4c2a b600 1259
0x0000030: 4d2b 5912 08b8 0016 0305 01b8 0018 9900
0x0000040: 4b2b b600 133b 2cb6 0013 1aa4 0032 bb00
0x0000050: 0a59 2c4c 1a04 603b 4e4d 2b59 c700 0dbb
0x0000060: 000d 5912 07b7 0015 bf1a b600 1459 1203
0x0000070: b800 164b 2c2d 2ab7 0011 a700 10bb 000a
0x0000080: 5912 01b7 0011 a700 042a 57b1
Stackmap Table:
full_frame(@105,{Integer,Top,Object[#10],Object[#10]},{Object[#12]})
full_frame(@125,{},{})
append_frame(@137,Object[#10])
full_frame(@138,{},{Object[#10]})

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)
4 Attachments

Related

Bugs: #10
Bugs: #12

Discussion

  • max-kammerer

    max-kammerer - 2017-10-11

    Simplified case :

    class C(val a: Int, val xs: List<Int>)
    
    fun main(args: Array<String>) {
        println(C(42, listOf("1").map { it.toInt() }))
    }
    
     
  • max-kammerer

    max-kammerer - 2017-10-11

    Bytecode before transfromation
    public static final void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
    stack=4, locals=16, args_size=1
    0: aload_0
    1: ldc #9 // String args
    3: invokestatic #15 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
    6: new #17 // class test/C
    9: dup
    10: bipush 42
    12: ldc #19 // String 1
    14: invokestatic #25 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
    17: checkcast #27 // class java/lang/Iterable
    20: astore_1
    21: istore 13
    23: astore 12
    25: astore 11
    27: aload_1
    28: astore_2
    29: new #29 // class java/util/ArrayList
    32: dup
    33: aload_1
    34: bipush 10
    36: invokestatic #33 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
    39: invokespecial #37 // Method java/util/ArrayList."<init>":(I)V
    42: checkcast #39 // class java/util/Collection
    45: astore_3
    46: aload_2
    47: invokeinterface #43, 1 // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    52: astore 4
    54: aload 4
    56: invokeinterface #49, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
    61: ifeq 110
    64: aload 4
    66: invokeinterface #53, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    71: astore 5
    73: aload_3
    74: aload 5
    76: checkcast #55 // class java/lang/String
    79: astore 6
    81: astore 14
    83: aload 6
    85: astore 7
    87: aload 7
    89: invokestatic #61 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
    92: invokestatic #65 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    95: astore 15
    97: aload 14
    99: aload 15
    101: invokeinterface #69, 2 // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
    106: pop
    107: goto 54
    110: aload_3
    111: checkcast #71 // class java/util/List
    114: astore 14
    116: aload 11
    118: aload 12
    120: iload 13
    122: aload 14
    124: invokespecial #74 // Method test/C."<init>":(ILjava/util/List;)V
    127: astore_1
    128: getstatic #80 // Field java/lang/System.out:Ljava/io/PrintStream;
    131: aload_1
    132: invokevirtual #86 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
    135: return
    LocalVariableTable:
    Start Length Slot Name Signature
    83 9 6 it Ljava/lang/String;
    83 9 8 $i$a$1$map I
    73 34 5 item$iv$iv Ljava/lang/Object;
    46 65 2 $receiver$iv$iv Ljava/lang/Iterable;
    46 65 3 destination$iv$iv Ljava/util/Collection;
    46 65 9 $i$f$mapTo I
    27 87 1 $receiver$iv Ljava/lang/Iterable;
    27 87 10 $i$f$map I
    0 136 0 args [Ljava/lang/String;
    LineNumberTable:
    line 6: 6
    line 8: 27
    line 9: 46
    line 10: 73
    line 6: 83
    line 6: 92
    line 9: 107
    line 11: 110
    line 6: 124
    line 7: 135
    StackMapTable: number_of_entries = 2
    frame_type = 255 / full_frame /
    offset_delta = 54
    locals = [ class "[Ljava/lang/String;", class java/lang/Iterable, class java/lang/Iterable, class java/util/Collection, class java/util/Iterator, top, top, top, top, top, top, uninitialized 6, uninitialized 6, int ]
    stack = []
    frame_type = 55 / same /</init></init>

    and after
    public static final void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
    stack=4, locals=6, args_size=1
    0: aload_0
    1: ldc #2 // String args
    3: invokestatic #25 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
    6: new #17 // class test/a
    9: dup
    10: ldc #1 // String 1
    12: invokestatic #24 // Method kotlin/collections/CollectionsKt.listOf:(Ljava/lang/Object;)Ljava/util/List;
    15: checkcast #6 // class java/lang/Iterable
    18: astore_0
    19: astore 4
    21: astore_3
    22: aload_0
    23: astore_1
    24: new #10 // class java/util/ArrayList
    27: dup
    28: aload_0
    29: bipush 10
    31: invokestatic #23 // Method kotlin/collections/CollectionsKt.collectionSizeOrDefault:(Ljava/lang/Iterable;I)I
    34: invokespecial #22 // Method java/util/ArrayList."<init>":(I)V
    37: checkcast #11 // class java/util/Collection
    40: astore_0
    41: aload_1
    42: invokeinterface #27, 1 // InterfaceMethod java/lang/Iterable.iterator:()Ljava/util/Iterator;
    47: astore_1
    48: aload_1
    49: invokeinterface #29, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
    54: ifeq 94
    57: aload_1
    58: invokeinterface #30, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    63: astore_2
    64: aload_0
    65: aload_2
    66: checkcast #8 // class java/lang/String
    69: astore_2
    70: astore 5
    72: aload_2
    73: dup
    74: astore_2
    75: invokestatic #20 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
    78: invokestatic #21 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    81: astore_2
    82: aload 5
    84: aload_2
    85: invokeinterface #28, 2 // InterfaceMethod java/util/Collection.add:(Ljava/lang/Object;)Z
    90: pop
    91: goto 48
    94: aload_0
    95: checkcast #13 // class java/util/List
    98: astore 5
    100: aload_3
    101: aload 4
    103: bipush 42
    105: aload 5
    107: invokespecial #26 // Method test/a."<init>":(ILjava/util/List;)V
    110: astore_0
    111: getstatic #18 // Field java/lang/System.out:Ljava/io/PrintStream;
    114: aload_0
    115: invokevirtual #19 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
    118: return
    StackMapTable: number_of_entries = 2
    frame_type = 255 / full_frame /
    offset_delta = 48
    locals = [ class java/util/Collection, class java/util/Iterator, top, class test/a, class test/a ]
    stack = []
    frame_type = 255 / full_frame /
    offset_delta = 45
    locals = [ class java/util/Collection, top, top, class test/a, class test/a ]
    stack = []</init></init>

     
  • Eric Lafortune

    Eric Lafortune - 2017-10-24

    Thanks for your report. ProGuard 6.0 beta1 is coming up in a few days, with some improvements to the preverification step. We'll have to check if this issue has been fixed.

     
    • max-kammerer

      max-kammerer - 2018-06-06

      Yes, it works with 6.0.3

       
  • T. Neidhart

    T. Neidhart - 2019-12-06
    • status: open --> closed-fixed
    • Priority: 5 --> High
     
  • T. Neidhart

    T. Neidhart - 2019-12-06

    Problem fixed in 6.0.3

     

Log in to post a comment.

MongoDB Logo MongoDB