Weijun Huang

25 papers B 1Misc 1Journal 18Unranked 5
YearRankTypeTitle / Venue / Authors
2026 J jnl
Digit. Signal Process.
Runze Hu, Tong Wang, Weijun Huang, Weichen Cui
2025 J jnl
Fuzzy Sets Syst.
Zihao Wu, Weijun Huang, Kai Huang, Zhi Liu, Guanyu Lai, Hanzhen Xiao, C. L. Philip Chen
2025 J jnl
BMC Medical Imaging
Minying Zhong, Deli Chen, Jieyi Ye, Yinting Chen, Chi Ma, Sixin Cheng, Weijun Huang, Shijun Qiu
2025 J jnl
Comput. Methods Programs Biomed.
Haoran Dou, Yuhao Huang, Yunzhi Huang, Xin Yang, Chaojiong Zhen, Yuanji Zhang, Yi Xiong, Weijun Huang, Dong Ni
2025 B conf
GLOBECOM
Weijun Huang, Chen-Khong Tham
2024 J jnl
Remote. Sens.
Weijun Huang, Tong Wang, Kun Liu
2024 J jnl
J. Cyber Secur. Mobil.
Jun Li, Weijun Huang
2024 J jnl
Remote. Sens.
Kun Liu, Tong Wang, Weijun Huang
2024 J jnl
Medical Image Anal.
Chaoyu Chen, Xin Yang, Yuhao Huang, Wenlong Shi, Yan Cao, Mingyuan Luo, Xindi Hu, Lei Zhu, Lequan Yu, Kejuan Yue, Yuanji Zhang, Yi Xiong, Dong Ni, Weijun Huang
2024 J jnl
Signal Process.
Weichen Cui, Tong Wang, Degen Wang, Weijun Huang
2024 J jnl
CoRR
Shuzhen Li, Yuxin Chen, Xuesong Chen, Ruiyang Gao, Yupeng Zhang, Chao Yu, Yunfei Li, Ziyi Ye, Weijun Huang, Hongliang Yi, Yue Leng, Yi Wu
2024 J jnl
Proc. ACM Interact. Mob. Wearable Ubiquitous Technol.
Shuzhen Li, Yuxin Chen, Xuesong Chen, Ruiyang Gao, Yupeng Zhang, Chao Yu, Yunfei Li, Ziyi Ye, Weijun Huang, Hongliang Yi, Yue Leng, Yi Wu
2023 conf
EMBC
Weijun Huang, Jia Huang, Guowei Wang, Hongzhou Lu, Min He, Wenjin Wang
2023 conf
CVPR Workshops
Haowen Wang, Weijun Huang, Jia Huang, Guowei Wang, Hongzhou Lu, Wenjin Wang
2023 Misc conf
ICASSP
Weijun Huang, Jia Huang, Guowei Wang, Hongzhou Lu, Min He, Wenjin Wang
2023 J jnl
CoRR
Chaoyu Chen, Xin Yang, Yuhao Huang, Wenlong Shi, Yan Cao, Mingyuan Luo, Xindi Hu, Lei Zhue, Lequan Yu, Kejuan Yue, Yuanji Zhang, Yi Xiong, Dong Ni, Weijun Huang
2022 conf
MICCAI (4)
Yuxin Zou, Haoran Dou, Yuhao Huang, Xin Yang, Jikuan Qian, Chaojiong Zhen, Xiaodan Ji, Nishant Ravikumar, Guoqiang Chen, Weijun Huang, Alejandro F. Frangi, Dong Ni
2022 J jnl
CoRR
Yuxin Zou, Haoran Dou, Yuhao Huang, Xin Yang, Jikuan Qian, Chaojiong Zhen, Xiaodan Ji, Nishant Ravikumar, Guoqiang Chen, Weijun Huang, Alejandro F. Frangi, Dong Ni
2021 J jnl
Multim. Tools Appl.
Weijun Huang, Bo Cheng, Gang Zhang, Yuexin Sui, Li Jiang, Yuan Xu, Hongting Li, Zhen Yang
2019 J jnl
Comput. Law Secur. Rev.
Weijun Huang, Xiaoqiu Li
2018 conf
ICIT
Qing Wu, Weigang Xu, Weijun Huang
2016 J jnl
J. Comput. Methods Sci. Eng.
Weiguo Lin, Weijun Huang, Jianwei Guo, Min Zhang
2015 J jnl
Int. J. Mechatronics Autom.
Qin Zhang, Chenying Xu, Weijun Huang, Hisayuki Aoyama
2014 J jnl
J. Optim. Theory Appl.
Weijun Huang
2009 conf
ESIAT (1)
Feipeng Xiao, Weijun Huang, Zhigang Zhang
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"