Kai Zhao

55 papers A* 8A 2Journal 39Unranked 6
YearRankTypeTitle / Venue / Authors
2026 A* conf
AAAI
Kai Zhao, Liting Ruan, Haoran Jiang, Xiaoqiang Zhu, Xianchao Zhang, Dan Zeng
2026 J jnl
Medical Image Anal.
Kai Zhao, Alex Ling Yu Hung, Kaifeng Pang, Parsa Hajipour, Holden H. Wu, Steven S. Raman, Kyunghyun Sung
2026 J jnl
CoRR
Wenli Li, Kai Zhao, Haoran Jiang, Enquan Yang, Yi Su, Dan Zeng
2025 conf
ISBI
Kaifeng Pang, Qi Miao, Alex Ling Yu Hung, Kai Zhao, Eunsun Oh, Raymi Ramirez, Wayne Brisbane, Kyunghyun Sung
2025 J jnl
IEEE Trans. Medical Imaging
Kai Zhao, Kaifeng Pang, Alex Ling Yu Hung, Haoxin Zheng, Ran Yan, Kyunghyun Sung
2025 conf
ISBI
Alex Ling Yu Hung, Kai Zhao, Kaifeng Pang, Qi Miao, Zhaozhi Wang, Wayne Brisbane, Demetri Terzopoulos, Kyunghyun Sung
2025 J jnl
Comput. Biol. Medicine
Kaifeng Pang, Kai Zhao, Alex Ling Yu Hung, Haoxin Zheng, Ran Yan, Kyunghyun Sung
2025 J jnl
CoRR
Kai Zhao, Wubang Yuan, Zheng Wang, Guanyi Li, Xiaoqiang Zhu, Deng-Ping Fan, Dan Zeng
2025 J jnl
CoRR
Kai Zhao, Wubang Yuan, Alex Ling Yu Hung, Dan Zeng
2025 J jnl
CoRR
Weiyi Lv, Ning Zhang, Hanyang Sun, Haoran Jiang, Kai Zhao, Jing Xiao, Dan Zeng
2024 J jnl
Pattern Recognit. Lett.
Kai Zhao, Tao Wang, Ruixin Zhang, Wei Shen
2024 A conf
WACV
Alex Ling Yu Hung, Haoxin Zheng, Kai Zhao, Xiaoxi Du, Kaifeng Pang, Qi Miao, Steven S. Raman, Demetri Terzopoulos, Kyunghyun Sung
2024 conf
MICCAI (8)
Alex Ling Yu Hung, Haoxin Zheng, Kai Zhao, Kaifeng Pang, Demetri Terzopoulos, Kyunghyun Sung
2024 J jnl
CoRR
Alex Ling Yu Hung, Haoxin Zheng, Kai Zhao, Kaifeng Pang, Demetri Terzopoulos, Kyunghyun Sung
2024 J jnl
CoRR
Kai Zhao, Zuojie He, Alex Ling Yu Hung, Dan Zeng
2024 J jnl
IEEE Trans. Multim.
Fu-Zhao Ou, Xingyu Chen, Kai Zhao, Shiqi Wang, Yuan-Gen Wang, Sam Kwong
2023 J jnl
CoRR
Alex Ling Yu Hung, Haoxin Zheng, Kai Zhao, Xiaoxi Du, Kaifeng Pang, Qi Miao, Steven S. Raman, Demetri Terzopoulos, Kyunghyun Sung
2023 J jnl
IEEE Access
Jiahao Lin, Qi Miao, Chuthaporn Surawech, Steven S. Raman, Kai Zhao, Holden H. Wu, Kyunghyun Sung
2023 J jnl
CoRR
Kai Zhao, Alex Ling Yu Hung, Kaifeng Pang, Haoxin Zheng, Kyunghyun Sung
2023 A* conf
ICCV
Lei Shen, Jianlong Jin, Ruixin Zhang, Huaen Li, Kai Zhao, Yingyi Zhang, Jingyun Zhang, Shouhong Ding, Yang Zhao, Wei Jia
2023 J jnl
CoRR
Lei Shen, Jianlong Jin, Ruixin Zhang, Huaen Li, Kai Zhao, Yingyi Zhang, Jingyun Zhang, Shouhong Ding, Yang Zhao, Wei Jia
2022 J jnl
IEEE Trans. Geosci. Remote. Sens.
Jia Li, Junjie Zhang, Fansheng Chen, Kai Zhao, Dan Zeng
2022 conf
ECCV (13)
Kai Zhao, Lei Shen, Yingyi Zhang, Chuhan Zhou, Tao Wang, Ruixin Zhang, Shouhong Ding, Wei Jia, Wei Shen
2022 A* conf
CVPR
Xuehui Wang, Kai Zhao, Ruixin Zhang, Shouhong Ding, Yan Wang, Wei Shen
2022 J jnl
CoRR
Xuehui Wang, Kai Zhao, Ruixin Zhang, Shouhong Ding, Yan Wang, Wei Shen
2022 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Kai Zhao, Qi Han, Chang-Bin Zhang, Jun Xu, Ming-Ming Cheng
2022 J jnl
Pattern Recognit.
Lei Shen, Yingyi Zhang, Kai Zhao, Ruixin Zhang, Wei Shen
2022 J jnl
CoRR
Kai Zhao, Lei Shen, Yingyi Zhang, Chuhan Zhou, Tao Wang, Ruixin Zhang, Shouhong Ding, Wei Jia, Wei Shen
2022 J jnl
Neurocomputing
Kai Zhao, Xuehui Wang, Xingyu Chen, Ruixin Zhang, Wei Shen
2022 J jnl
CoRR
Ge-Peng Ji, Guobao Xiao, Yu-Cheng Chou, Deng-Ping Fan, Kai Zhao, Geng Chen, Huazhu Fu, Luc Van Gool
2022 J jnl
Int. J. Autom. Comput.
Ge-Peng Ji, Guobao Xiao, Yu-Cheng Chou, Deng-Ping Fan, Kai Zhao, Geng Chen, Luc Van Gool
2021 J jnl
CoRR
Tao Wang, Ruixin Zhang, Xingyu Chen, Kai Zhao, Xiaolin Huang, Yuge Huang, Shaoxin Li, Jilin Li, Feiyue Huang
2021 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Wei Shen, Yilu Guo, Yan Wang, Kai Zhao, Bo Wang, Alan L. Yuille
2021 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Shanghua Gao, Ming-Ming Cheng, Kai Zhao, Xin-Yu Zhang, Ming-Hsuan Yang, Philip H. S. Torr
2021 A conf
UAI
Xin-Yu Zhang, Kai Zhao, Taihong Xiao, Ming-Ming Cheng, Ming-Hsuan Yang
2020 conf
ECCV (9)
Qi Han, Kai Zhao, Jun Xu, Ming-Ming Cheng
2020 J jnl
CoRR
Qi Han, Kai Zhao, Jun Xu, Ming-Ming Cheng
2020 J jnl
CoRR
Kai Zhao, Xin-Yu Zhang, Qi Han, Ming-Ming Cheng
2020 J jnl
CoRR
Xin-Yu Zhang, Kai Zhao, Taihong Xiao, Ming-Ming Cheng, Ming-Hsuan Yang
2019 J jnl
CoRR
Wei Shen, Yilu Guo, Yan Wang, Kai Zhao, Bo Wang, Alan L. Yuille
2019 A* conf
ICCV
Kai Zhao, Shanghua Gao, Wenguan Wang, Ming-Ming Cheng
2019 A* conf
CVPR
Kai Zhao, Jingyi Xu, Ming-Ming Cheng
2019 J jnl
CoRR
Shanghua Gao, Ming-Ming Cheng, Kai Zhao, Xin-Yu Zhang, Ming-Hsuan Yang, Philip H. S. Torr
2018 J jnl
J. Electronic Imaging
Dandan Li, Dan Zeng, Kai Zhao
2018 A* conf
CVPR
Wei Shen, Yilu Guo, Yan Wang, Kai Zhao, Bo Wang, Alan L. Yuille
2018 A* conf
IJCAI
Kai Zhao, Wei Shen, Shanghua Gao, Dandan Li, Ming-Ming Cheng
2018 J jnl
CoRR
Kai Zhao, Wei Shen, Shanghua Gao, Dandan Li, Ming-Ming Cheng
2018 J jnl
CoRR
Kai Zhao, Shanghua Gao, Qibin Hou, Dandan Li, Ming-Ming Cheng
2017 J jnl
CoRR
Wei Shen, Yilu Guo, Yan Wang, Kai Zhao, Bo Wang, Alan L. Yuille
2017 J jnl
IEEE Trans. Image Process.
Wei Shen, Kai Zhao, Yuan Jiang, Yan Wang, Xiang Bai, Alan L. Yuille
2017 conf
NIPS
Wei Shen, Kai Zhao, Yilu Guo, Alan L. Yuille
2017 J jnl
CoRR
Wei Shen, Kai Zhao, Yilu Guo, Alan L. Yuille
2016 J jnl
CoRR
Wei Shen, Kai Zhao, Yuan Jiang, Yan Wang, Xiang Bai, Alan L. Yuille
2016 A* conf
CVPR
Wei Shen, Kai Zhao, Yuan Jiang, Yan Wang, Zhijiang Zhang, Xiang Bai
2016 J jnl
CoRR
Wei Shen, Kai Zhao, Yuan Jiang, Yan Wang, Zhijiang Zhang, Xiang Bai
tests/unit/test_apk_jadx_wrapper.py
← Index tests/unit/test_apk_jadx_wrapper.py python
"""
Unit tests for JADX wrapper subprocess management and output parsing.

All subprocess calls are mocked — no JADX/Java installation required.
"""
import os
import tempfile
import textwrap

import pytest
from unittest.mock import MagicMock, patch, call

pytestmark = [pytest.mark.unit, pytest.mark.apk, pytest.mark.decompile]


class TestJADXDecompiler:
    """Tests for JADXDecompiler subprocess wrapper."""

    @patch.dict(os.environ, {}, clear=False)
    def test_init_defaults(self):
        os.environ.pop("JADX_PATH", None)
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler()
        assert j.jadx_path == "jadx"
        assert j.timeout == 300

    def test_init_custom_path(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler(jadx_path="/usr/local/bin/jadx", timeout=300)
        assert j.jadx_path == "/usr/local/bin/jadx"
        assert j.timeout == 300

    def test_init_from_env(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        with patch.dict(os.environ, {"JADX_PATH": "/opt/jadx/bin/jadx", "JADX_TIMEOUT": "120"}):
            j = JADXDecompiler()
            assert j.jadx_path == "/opt/jadx/bin/jadx"
            assert j.timeout == 120

    @patch("subprocess.Popen")
    def test_decompile_success(self, mock_popen):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        mock_proc = MagicMock()
        mock_proc.communicate.return_value = ("output", "")
        mock_proc.returncode = 0
        mock_popen.return_value = mock_proc

        j = JADXDecompiler()
        result = j.decompile("/test.apk", "/output")
        assert result is True

    @patch("subprocess.Popen")
    def test_decompile_nonzero_exit_no_sources(self, mock_popen):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        mock_proc = MagicMock()
        mock_proc.communicate.return_value = ("", "error msg")
        mock_proc.returncode = 1
        mock_popen.return_value = mock_proc

        j = JADXDecompiler(log=MagicMock())
        result = j.decompile("/test.apk", "/nonexistent_output")
        assert result is False

    @patch("subprocess.Popen")
    def test_decompile_timeout(self, mock_popen):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        import subprocess
        mock_proc = MagicMock()
        mock_proc.communicate.side_effect = subprocess.TimeoutExpired(cmd="jadx", timeout=10)
        mock_proc.pid = 12345
        mock_popen.return_value = mock_proc

        with patch("os.getpgid", return_value=12345), \
             patch("os.killpg"):
            j = JADXDecompiler(timeout=10, log=MagicMock())
            result = j.decompile("/test.apk", "/output")
            assert result is False

    @patch("subprocess.Popen", side_effect=FileNotFoundError)
    def test_decompile_not_found(self, mock_popen):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler(log=MagicMock())
        result = j.decompile("/test.apk", "/output")
        assert result is False

    @patch("subprocess.Popen")
    def test_decompile_command_args(self, mock_popen):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        mock_proc = MagicMock()
        mock_proc.communicate.return_value = ("", "")
        mock_proc.returncode = 0
        mock_popen.return_value = mock_proc

        j = JADXDecompiler(jadx_path="/opt/jadx")
        j.decompile("/test.apk", "/output")

        cmd = mock_popen.call_args[0][0]
        assert cmd[0] == "/opt/jadx"
        assert "--no-res" in cmd
        assert "--no-imports" in cmd
        assert "--threads-count" in cmd
        assert "/test.apk" in cmd

    def test_parse_java_methods_empty_dir(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler()
        result = j.parse_java_methods("/nonexistent")
        assert result == {}

    def test_parse_java_methods_with_files(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        with tempfile.TemporaryDirectory() as tmpdir:
            sources_dir = os.path.join(tmpdir, "sources", "com", "example")
            os.makedirs(sources_dir)

            java_content = textwrap.dedent("""\
                package com.example;

                public class MyClass {
                    public void doStuff(int x) {
                        System.out.println(x);
                    }

                    private String getName() {
                        return "test";
                    }
                }
            """)
            with open(os.path.join(sources_dir, "MyClass.java"), "w") as f:
                f.write(java_content)

            j = JADXDecompiler()
            methods = j.parse_java_methods(tmpdir)
            assert len(methods) >= 1

    def test_extract_methods_from_java(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        source = textwrap.dedent("""\
            public void foo(int x) {
                if (x > 0) {
                    System.out.println(x);
                }
            }
        """)
        j = JADXDecompiler()
        methods = j._extract_methods_from_java(source, "com.example.Test")
        assert len(methods) == 1
        key = list(methods.keys())[0]
        assert "foo" in key

    def test_is_method_declaration_valid(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler()
        result = j._is_method_declaration("    public void foo(int x) {")
        assert result is not None
        assert result[0] == "foo"

    def test_is_method_declaration_control_flow(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler()
        # 'if', 'for', etc. should not be recognized as methods
        assert j._is_method_declaration("        if (x > 0) {") is None
        assert j._is_method_declaration("        for (int i = 0; i < 10; i++) {") is None

    def test_is_method_declaration_static(self):
        from redb.extractors.decompiler.apk.jadx_wrapper import JADXDecompiler
        j = JADXDecompiler()
        result = j._is_method_declaration("    public static void main(String[] args) {")
        assert result is not None
        assert result[0] == "main"