Skip to content

[core] UnsupportedOperationException in SwitchRegionMaker for consecutive packed-switches #2882

Description

@obus-globus

Issue details

A method with two consecutive packed-switch instructions on the same register, with cases converging to a shared block, crashes RegionMakerVisitor; the method falls back to a "Method not decompiled" stub.

SwitchRegionMaker.insertBreaksForCase appends a break with region.getSubBlocks().add(...) (SwitchRegionMaker.java:419). For IfRegion, SwitchRegion and TryCatchRegion, getSubBlocks() returns an unmodifiable list, so the add throws.

Working around the crash locally shows the decompilation is also wrong for this shape: the second packed-switch comes out as an empty switch with its cases and default dropped. So the root issue looks like reconstruction of the consecutive same-register packed-switch, not the add itself.

Different shape, possibly related: #2479.

Relevant log output or stacktrace

java.lang.UnsupportedOperationException
	at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1093)
	at jadx.core.dex.visitors.regions.maker.SwitchRegionMaker$1.leaveRegion(SwitchRegionMaker.java:419)
	at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverseInternal(DepthRegionTraversal.java:91)
	at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverse(DepthRegionTraversal.java:31)
	at jadx.core.dex.visitors.regions.maker.SwitchRegionMaker.insertBreaksForCase(SwitchRegionMaker.java:399)
	at jadx.core.dex.visitors.regions.maker.SwitchRegionMaker.insertBreaks(SwitchRegionMaker.java:89)
	at jadx.core.dex.visitors.regions.PostProcessRegions.leaveRegion(PostProcessRegions.java:31)
	at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverseInternal(DepthRegionTraversal.java:91)
	at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverse(DepthRegionTraversal.java:27)
	at jadx.core.dex.visitors.regions.PostProcessRegions.process(PostProcessRegions.java:21)
	at jadx.core.dex.visitors.regions.RegionMakerVisitor.visit(RegionMakerVisitor.java:31)

Provide sample and class/method full name

Standalone smali, reproduces on current master (8c28a85). Assemble with smali, then run jadx on the dex:

.class public LTrigger;
.super Ljava/lang/Object;

.method public static test(I)V
    .registers 2
    const/4 v0, -0x1
    if-eq p0, v0, :join
    if-eqz p0, :join
    const/4 v0, 0x1
    if-eq p0, v0, :join
    packed-switch p0, :pd1
    packed-switch p0, :pd2
    return-void
    :case1
    goto :join
    :case2
    nop
    :join
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    invoke-virtual {v0, p0}, Ljava/io/PrintStream;->println(I)V
    return-void
    :pd1
    .packed-switch 0x1e
        :case1
        :case1
    .end packed-switch
    :pd2
    .packed-switch 0x28
        :case2
        :case2
    .end packed-switch
.end method

Also in a public app: com.rubenmayayo.reddit (Boost for Reddit) 1.12.12, methods PreferenceFragmentPosts.f, SavedSortsActivity.u1, PreferenceFragmentPostsCompat.handleMenuItemSelected.

Jadx version

master 8c28a85 (current HEAD)

Metadata

Metadata

Assignees

Labels

CoreIssues in jadx-core moduleswitch

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions