Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] "Failed to restore switch over string" on reconstructed switch #2333

Closed
pubiqq opened this issue Oct 31, 2024 · 1 comment
Closed
Labels
bug Core Issues in jadx-core module

Comments

@pubiqq
Copy link
Contributor

pubiqq commented Oct 31, 2024

Provide sample and class/method full name

Test

package jadx.tests.integration.switches;

import org.junit.jupiter.api.Test;

import jadx.tests.api.IntegrationTest;
import jadx.tests.api.utils.assertj.JadxAssertions;

import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;

public class TestSwitchOverStrings3 extends IntegrationTest {

    public static class TestCls {

        /**
         * Switch statement reconstructed from bytecode.
         * <p>
         * Original:
         *
         * <pre>
         * {@code
         * // Strings 'frewhyh', 'phgafkp' and 'ucguedt' have same hash code.
         * public int test(String str) {
         *     switch (str) {
         *         case "frewhyh":
         *             return 1;
         *         case "phgafkp":
         *             return 2;
         *         case "test":
         *         case "test2":
         *             return 3;
         *         case "other":
         *             return 4;
         *         default:
         *             return 0;
         *     }
         * }
         * }
         * </pre>
         */
        public int test(String str) {
            char c = 65535;
            switch (str.hashCode()) {
                case -603257287:
                    if (!str.equals("phgafkp")) {
                        if (str.equals("frewhyh")) {
                            c = 0;
                            break;
                        }
                    } else {
                        c = 1;
                        break;
                    }
                    break;
                case 3556498:
                    if (str.equals("test")) {
                        c = 2;
                        break;
                    }
                    break;
                case 106069776:
                    if (str.equals("other")) {
                        c = 4;
                        break;
                    }
                    break;
                case 110251488:
                    if (str.equals("test2")) {
                        c = 3;
                        break;
                    }
                    break;
            }
            switch (c) {
                case 0:
                    return 1;
                case 1:
                    return 2;
                case 2:
                case 3:
                    return 3;
                case 4:
                    return 4;
                default:
                    return 0;
            }
        }

        public void check() {
            JadxAssertions.assertThat(test("frewhyh")).isEqualTo(1);
            JadxAssertions.assertThat(test("phgafkp")).isEqualTo(2);
            JadxAssertions.assertThat(test("test")).isEqualTo(3);
            JadxAssertions.assertThat(test("test2")).isEqualTo(3);
            JadxAssertions.assertThat(test("other")).isEqualTo(4);
            JadxAssertions.assertThat(test("unknown")).isEqualTo(0);
            JadxAssertions.assertThat(test("ucguedt")).isEqualTo(0);
        }
    }

    @Test
    public void test() {
        assertThat(getClassNode(TestCls.class))
                .code()
                .doesNotContain("case -603257287:")
                .doesNotContain("c = ")
                .containsOne("case \"frewhyh\":")
                .countString(5, "return ");
    }
}

@pubiqq pubiqq added bug Core Issues in jadx-core module labels Oct 31, 2024
@skylot
Copy link
Owner

skylot commented Nov 1, 2024

I applied quick fix for negation check.
And looks like other check should not happen because of normalize, also simplify do a lot of changes to conditions, so maybe it not play well with normalize.
Anyway, this fix covers both cases and not depend on how normalize work (or not 🤣).

@skylot skylot closed this as completed Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Core Issues in jadx-core module
Projects
None yet
Development

No branches or pull requests

2 participants