Xiaojun Zheng

36 papers B 3C 16Journal 12Unranked 5
YearRankTypeTitle / Venue / Authors
2025 conf
BDICN
Yunpeng Li, Xiaojun Zheng, Yalin Wang
2025 J jnl
Comput.
Xiaojun Zheng, Rundong Liu, Xiaoyang Liu
2024 C conf
CSCWD
Xiao Dong, Xiaojun Zheng, Yaning Song
2023 C conf
CSCWD
Xingze Guo, Feng Gao, Xiaojun Zheng, Shiduo Ning
2023 J jnl
Technometrics
Xiaojun Zheng, Simon Mak, Liyan Xie, Yao Xie
2023 C conf
CSCWD
Feng Gao, Xingze Guo, Xiaojun Zheng, Shiduo Ning
2023 J jnl
Symmetry
Xiaojun Zheng, Feng Gao, Xiaoying Tong
2022 C conf
CSCWD
Donglin Liang, Tao Li, Jiajian Li, Xiaojun Zheng, Yanjun Shi
2022 C conf
CSCWD
Hongna Lou, Fangyi Hu, Jiajian Li, Xiaojun Zheng, Yanjun Shi
2022 J jnl
Sensors
Yanbin Gao, Xiaojun Zheng, Hao Wang, Wenkang Luo
2022 C conf
CSCWD
Xiaojun Zheng, Renhao Zheng, Shiduo Ning
2022 C conf
CSCWD
Xiaojun Zheng, Qixian Wu, Jiang Zhong
2022 conf
ICCIR
Yuzhong Liu, Hualiang Li, Jianmin Wang, Haochuan Zhang, Xiaojun Zheng
2021 C conf
CSCWD
Shiduo Ning, Jiang Zhong, Xiaojun Zheng
2021 J jnl
IEEE Access
Xiaojun Zheng, Shiduo Ning, Hao Sun, Jiang Zhong, Xiaoying Tong
2019 C conf
CSCWD
Xiaojun Zheng, Jiang Zhong, Yanbin Sun, Yanjun Shi, Zhizheng Xu, Hao Sun
2019 C conf
CSCWD
Xiaozhen Mi, Mengting Mei, Xiaojun Zheng
2018 J jnl
Neural Comput. Appl.
Zhuang-Cheng Liu, Luyang Hou, Yanjun Shi, Xiaojun Zheng, Hongfei Teng
2018 J jnl
CoRR
So Mang Han, Taylor Okonek, Nikesh Yadav, Xiaojun Zheng
2018 C conf
CSCWD
Xueyan Sun, Yingkai Zhao, Shuhuai Shen, Kefei Wang, Xiaojun Zheng, Yanjun Shi
2017 J jnl
SIAM J. Imaging Sci.
Jun Liu, Xiaojun Zheng
2017 C conf
CSCWD
Yanjun Shi, Xueyan Sun, Wang Chen, Rong Xie, Xiaojun Zheng
2017 C conf
CSCWD
Yong Liu, Wang Chen, Jianjun Hu, Xiaojun Zheng, Yanjun Shi
2016 B conf
SMC
Yanjun Shi, Xianchao Wang, Xueyan Sun, Rong Xie, Xiaojun Zheng
2016 conf
MSN
Zhejie Shen, Xiaojun Zheng, Haijiang Xie
2016 conf
SSCI
Rui Wang, Hisao Ishibuchi, Yan Zhang, Xiaojun Zheng, Tao Zhang
2016 C conf
CSCWD
Luyang Hou, Zhuang-Cheng Liu, Yanjun Shi, Xiaojun Zheng
2015 J jnl
IEEE Commun. Lett.
Xiaojun Zheng, Erwu Liu, Zhengqing Zhang, Xinyu Qu, Rui Wang, Xuefeng Yin, Fuqiang Liu
2015 C conf
CSCWD
Yanjun Shi, Luyang Hou, Xiaojun Zheng
2014 C conf
ICCC
Zhengqing Zhang, Erwu Liu, Xiaojun Zheng, Yuhui Jian, Dong Wang, Dong Liu
2014 J jnl
Circuits Syst. Signal Process.
Ziquan Lin, Ping Zhao, Xiaojun Zheng
2014 B conf
PIMRC
Binbin Lv, Juan Xu, Xiaojun Zheng
2014 conf
CIPS-SIGHAN
Chao Che, Xiaojun Zheng
2013 B conf
WiMob
Yue Wang, Erwu Liu, Xiaojun Zheng, Zhengqing Zhang, Yuhui Jian, Xuefeng Yin, Fuqiang Liu
2013 J jnl
IEEE Commun. Lett.
Yue Wang, Erwu Liu, Yuhui Jian, Zhengqing Zhang, Xiaojun Zheng, Rui Wang, Fuqiang Liu, Xuefeng Yin
2004 J jnl
EURASIP J. Adv. Signal Process.
Feng Li, Jiaxiong Peng, Xiaojun Zheng
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"