Skip to content

lizhangqu/R8BugTest

Repository files navigation

Environment

  • Android Gradle Plugin 3.5.1
  • Gradle 5.6.2
  • R8 is enabled and minifyEnabled=true
  • R8 version 1.5.68 (build fe9439236985bdb8b4d51a186f9dc0bd3a2fa669 from go/r8bot (luci-r8-ci-archive-0-xz51))
  • applymapping is configured in proguard rule

Bug1

Reproduce code

The Java code

package com.sample.r8bugtest;

public interface TestClinit {
    Throwable t = new Throwable();

    //the <clinit> will be obfuscated when there is an applymapping rule in the proguard rule, but it should not be obfuscated actually.
    //Excetion (Method(Lcom/sample/r8bugtest/TestClinit;.a) is marked constructor, but doesn't match name) will be thrown in runtime.
}

The proguard-rules.pro file content

-keep class com.sample.r8bugtest.TestClinit {*;}
-applymapping mapping.txt

The mapping.txt file is empty.

# nothing here

Now run ./gradlew :bug1:assembleRelease

Bad result

The mapping file content generated by r8

# compiler: R8
# compiler_version: 1.5.68
# min_api: 16
# pg_map_id: 587a5bf
com.sample.r8bugtest.TestClinit -> com.sample.r8bugtest.TestClinit:
    void <clinit>() -> a

The smali code

.class public interface abstract Lcom/sample/r8bugtest/TestClinit;
.super Ljava/lang/Object;
.source ""


# static fields
.field public static final t:Ljava/lang/Throwable;


# direct methods
.method static constructor a()V
    .registers 1

    new-instance v0, Ljava/lang/Throwable;

    invoke-direct {v0}, Ljava/lang/Throwable;-><init>()V

    sput-object v0, Lcom/sample/r8bugtest/TestClinit;->t:Ljava/lang/Throwable;

    return-void
.end method

The <clinit> will be obfuscated when there is an applymapping rule in the proguard rule, but it should not be obfuscated actually. Excetion (Method(Lcom/sample/r8bugtest/TestClinit;.a) is marked constructor, but doesn't match name) will be thrown in runtime.

Bug2

Reproduce code

There are two compiled jars in runtime classpath in bug2/runtime dir called flutter.jar and video_plugin.jar. And There is a compiled jar in compileOnly classpath in bug2/compileOnly dir called palyer_sdk.jar

The gradle dependency is

dependencies {
    implementation fileTree(dir: 'runtime', include: ['*.jar'])
    compileOnly fileTree(dir: 'compileOnly', include: ['*.jar'])
}

The proguard-rules.pro file content

-keep class io.flutter.** {*;}
-keep class com.vdian.flutter.vd_video_player.VdVideoPlayerPlugin {*;}
-applymapping mapping.txt

The mapping.txt file content

com.vdian.android.lib.vdplayer.player.IMediaPlayer -> com.vdian.android.lib.vdplayer.player.IMediaPlayer:
com.vdian.android.lib.vdplayer.player.IMediaPlayer$OnBufferingUpdateListener -> com.vdian.android.lib.vdplayer.player.IMediaPlayer$OnBufferingUpdateListener:

Now run ./gradlew :bug2:assembleRelease

Bad result

The constructor code in class com.vdian.flutter.vd_video_player.VideoPlayer which is in video_plugin.jar file

import com.vdian.android.lib.vdplayer.player.IMediaPlayer;
import com.vdian.android.lib.vdplayer.player.VDMediaDataSource;
import com.vdian.android.lib.vdplayer.player.IMediaPlayer.OnBufferingUpdateListener;
import com.vdian.android.lib.vdplayer.player.IMediaPlayer.OnCompletionListener;
import com.vdian.android.lib.vdplayer.player.IMediaPlayer.OnErrorListener;
import com.vdian.android.lib.vdplayer.player.IMediaPlayer.OnPreparedListener;

public class VideoPlayer {
    private final IMediaPlayer mediaPlayer;
    private final EventChannel eventChannel;
    private final SurfaceTextureEntry textureEntry;
    private Surface surface;
    private boolean isInitialized = false;
    private QueuingEventSink eventSink = new QueuingEventSink();

    public VideoPlayer(Context context, IMediaPlayer mediaPlayer, EventChannel eventChannel, SurfaceTextureEntry textureEntry, String dataSource, Result result) {
        this.eventChannel = eventChannel;
        this.mediaPlayer = mediaPlayer;
        this.textureEntry = textureEntry;
        Uri uri = Uri.parse(dataSource);

        try {
            mediaPlayer.setDataSource(context, new VDMediaDataSource(uri));
        } catch (IOException var9) {
            var9.printStackTrace();
        }

        this.setupVideoPlayer(eventChannel, result);
    }
}

com.vdian.flutter.vd_video_player.VideoPlayer reference a class com.vdian.android.lib.vdplayer.player.IMediaPlayer which is in the play_sdk.jar in compileOnly classpath.

Actually com.vdian.android.lib.vdplayer.player.IMediaPlayer should not be obfuscated because it's just be provided and it's configured with mapping rule com.vdian.android.lib.vdplayer.player.IMediaPlayer -> com.vdian.android.lib.vdplayer.player.IMediaPlayer in the mapping.txt.

The mapping file content generated by r8(only part of it)

com.vdian.flutter.vd_video_player.VideoPlayer -> a.a.a.a.b:
    com.vdian.android.lib.vdplayer.player.IMediaPlayer mediaPlayer -> a
    com.vdian.flutter.vd_video_player.QueuingEventSink eventSink -> f
    io.flutter.plugin.common.EventChannel eventChannel -> b
    boolean isInitialized -> e
    android.view.Surface surface -> d
    io.flutter.view.TextureRegistry$SurfaceTextureEntry textureEntry -> c
    com.vdian.flutter.vd_video_player.QueuingEventSink access$000(com.vdian.flutter.vd_video_player.VideoPlayer) -> a
    boolean access$102(com.vdian.flutter.vd_video_player.VideoPlayer,boolean) -> a
    void access$300(com.vdian.flutter.vd_video_player.VideoPlayer,int) -> a
    void dispose() -> a
    void seekTo(int) -> a
    void setLooping(boolean) -> a
    void setVolume(double) -> a
    void setupVideoPlayer(io.flutter.plugin.common.EventChannel,io.flutter.plugin.common.MethodChannel$Result) -> a
    boolean access$100(com.vdian.flutter.vd_video_player.VideoPlayer) -> b
    long getPosition() -> b
    void sendBufferingUpdate(int) -> b
    void access$200(com.vdian.flutter.vd_video_player.VideoPlayer) -> c
    boolean isPlaying() -> c
    void pause() -> d
    void play() -> e
    void sendInitialized() -> f

We found the class com.vdian.flutter.vd_video_player.VideoPlayer has been obfuscated to a.a.a.a.b

The class a.a.a.a.b smali code generated by r8(only part of it)

.class public La/a/a/a/b;
.super Ljava/lang/Object;
.source ""

# direct methods
.method public constructor <init>(Landroid/content/Context;Lcom/vdian/android/lib/vdplayer/player/a;Lio/flutter/plugin/common/EventChannel;Lio/flutter/view/TextureRegistry$SurfaceTextureEntry;Ljava/lang/String;Lio/flutter/plugin/common/MethodChannel$Result;)V
    .registers 8

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    const/4 v0, 0x0

    iput-boolean v0, p0, La/a/a/a/b;->e:Z

    new-instance v0, La/a/a/a/a;

    invoke-direct {v0}, La/a/a/a/a;-><init>()V

    iput-object v0, p0, La/a/a/a/b;->f:La/a/a/a/a;

    iput-object p3, p0, La/a/a/a/b;->b:Lio/flutter/plugin/common/EventChannel;

    iput-object p2, p0, La/a/a/a/b;->a:Lcom/vdian/android/lib/vdplayer/player/a;

    iput-object p4, p0, La/a/a/a/b;->c:Lio/flutter/view/TextureRegistry$SurfaceTextureEntry;

    invoke-static {p5}, Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object p4

    :try_start_17
    new-instance p5, Lcom/vdian/android/lib/vdplayer/player/VDMediaDataSource;

    invoke-direct {p5, p4}, Lcom/vdian/android/lib/vdplayer/player/VDMediaDataSource;-><init>(Landroid/net/Uri;)V

    invoke-interface {p2, p1, p5}, Lcom/vdian/android/lib/vdplayer/player/a;->setDataSource(Landroid/content/Context;Lcom/vdian/android/lib/vdplayer/player/VDMediaDataSource;)V
    :try_end_1f
    .catch Ljava/io/IOException; {:try_start_17 .. :try_end_1f} :catch_20

    goto :goto_24

    :catch_20
    move-exception p1

    invoke-virtual {p1}, Ljava/io/IOException;->printStackTrace()V

    :goto_24
    invoke-direct {p0, p3, p6}, La/a/a/a/b;->a(Lio/flutter/plugin/common/EventChannel;Lio/flutter/plugin/common/MethodChannel$Result;)V

    return-void
.end method

com.vdian.android.lib.vdplayer.player.IMediaPlayer.setDataSource is be obfuscated to com.vdian.android.lib.vdplayer.player.a.setDataSource but there is a mapping rule in mapping file

com.vdian.android.lib.vdplayer.player.IMediaPlayer -> com.vdian.android.lib.vdplayer.player.IMediaPlayer

All of these bugs happened when applymapping is configured in proguard rule.

About

reproduce r8 bug

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages