Weiming Liu

95 papers A* 55A 2Journal 33Unranked 5
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Knowl. Data Eng.
Fan Wang, Chaochao Chen, Weiming Liu, Lianyong Qi, Xuyun Zhang, Yanchao Tan, Mengying Zhu, Xiaolin Zheng
2026 A* conf
AAAI
Yuwen Liu, Lianyong Qi, Xingyuan Mao, Weiming Liu, Xuhui Fan, Qiang Ni, Xuyun Zhang, Yang Zhang, Yuan Tian, Amin Beheshti
2026 A* conf
AAAI
Weiyi Zhong, Weiming Liu, Lianyong Qi, Xiaoran Zhao, Xiaolong Xu, Haolong Xiang, Yang Cao, Shichao Pei, Qiang Ni
2026 A* conf
WWW
Jianye Xie, Lianyong Qi, Weiming Liu, Anqi Wang, Xiaolong Xu, Haolong Xiang, Xuyun Zhang, Wenwen Gong, Yang Zhang, Amin Beheshti, Wanchun Dou
2026 A* conf
AAAI
Jiajie Su, Zihan Nan, Yunshan Ma, Xiaobo Xia, Xiaohua Feng, Weiming Liu, Xiang Chen, Xiaolin Zheng, Chaochao Chen
2026 A* conf
AAAI
Haodong Li, Lianyong Qi, Weiming Liu, Fan Wang, Chong Li, Shengye Pang, Wenwen Gong, Yanwei Xu, Xiaoxiao Chi, Yang Zhang, Xiaokang Zhou
2025 A* conf
IJCAI
Haodong Li, Lianyong Qi, Weiming Liu, Xiaolong Xu, Wanchun Dou, Yang Cao, Xuyun Zhang, Amin Beheshti, Xiaokang Zhou
2025 A* conf
ACM Multimedia
Te Song, Lianyong Qi, Weiming Liu, Fan Wang, Xiaolong Xu, Hongsheng Hu, Yang Cao, Xuyun Zhang, Amin Beheshti
2025 J jnl
IEEE Trans. Serv. Comput.
Jiajie Su, Xiaolin Zheng, Zibin Lin, Weiming Liu, Chaochao Chen, Jianwei Yin
2025 A* conf
AAAI
Fan Wang, Chaochao Chen, Weiming Liu, Minye Lei, Jintao Chen, Yuwen Liu, Xiaolin Zheng, Jianwei Yin
2025 A* conf
CVPR
Hua Yu, Weiming Liu, Gui Xu, Yaqing Hou, Yew-Soon Ong, Qiang Zhang
2025 J jnl
CoRR
Hua Yu, Weiming Liu, Gui Xu, Yaqing Hou, Yew-Soon Ong, Qiang Zhang
2025 A* conf
CVPR
Weiming Liu, Jun Dan, Fan Wang, Xinting Liao, Junhao Dong, Hua Yu, Shunjie Dong, Lianyong Qi
2025 J jnl
ACM Trans. Inf. Syst.
Jiajie Su, Chaochao Chen, Yihao Wang, Weiming Liu, Yuyuan Li, Tao Wang, Zhigang Li, Xiaolin Zheng, Jianwei Yin
2025 A* conf
ICML
Xiuyuan Wang, Chaochao Chen, Weiming Liu, Xinting Liao, Fan Wang, Xiaolin Zheng
2025 A* conf
AAAI
Te Song, Lianyong Qi, Weiming Liu, Fan Wang, Xiaolong Xu, Xuyun Zhang, Amin Beheshti, Xiaokang Zhou, Wanchun Dou
2025 A* conf
ICML
Xinting Liao, Weiming Liu, Jiaming Qian, Pengyang Zhou, Jiahe Xu, Wenjie Wang, Chaochao Chen, Xiaolin Zheng, Tat-Seng Chua
2025 J jnl
CoRR
Xinting Liao, Weiming Liu, Jiaming Qian, Pengyang Zhou, Jiahe Xu, Wenjie Wang, Chao-Chao Chen, Xiaolin Zheng, Tat-Seng Chua
2025 A conf
WSDM
Pengyang Zhou, Chaochao Chen, Weiming Liu, Xinting Liao, Fengyuan Yu, Zhihui Fu, Xingyu Lou, Wu Wen, Xiaolin Zheng, Jun Wang
2025 A* conf
AAAI
Pengyang Zhou, Chaochao Chen, Weiming Liu, Xinting Liao, Wenkai Shen, Jiahe Xu, Zhihui Fu, Jun Wang, Wu Wen, Xiaolin Zheng
2025 A* conf
WWW
Yuwen Liu, Lianyong Qi, Xingyuan Mao, Weiming Liu, Fan Wang, Xiaolong Xu, Xuyun Zhang, Wanchun Dou, Xiaokang Zhou, Amin Beheshti
2025 A* conf
ICML
Junhao Dong, Piotr Koniusz, Yifei Zhang, Hao Zhu, Weiming Liu, Xinghua Qu, Yew-Soon Ong
2025 J jnl
ACM Trans. Inf. Syst.
Fan Wang, Lianyong Qi, Weiming Liu, Bowen Yu, Jintao Chen, Yanwei Xu
2025 A* conf
SIGIR
Pengyang Zhou, Chaochao Chen, Weiming Liu, Wenkai Shen, Xinting Liao, Huarong Deng, Zhihui Fu, Jun Wang, Wu Wen, Xiaolin Zheng
2025 A* conf
WWW
Weiming Liu, Chaochao Chen, Jiahe Xu, Xinting Liao, Fan Wang, Xiaolin Zheng, Zhihui Fu, Ruiguang Pei, Jun Wang
2025 J jnl
CoRR
Weiming Liu, Chaochao Chen, Jiahe Xu, Xinting Liao, Fan Wang, Xiaolin Zheng, Zhihui Fu, Ruiguang Pei, Jun Wang
2025 A* conf
ACM Multimedia
Yijie Yang, Lianyong Qi, Weiming Liu, Fan Wang, Jing Du, Yuwen Liu, Xiaolong Xu, Qiang Ni, Wanchun Dou, Xiaokang Zhou
2025 conf
KDD (2)
Jiajie Su, Chaochao Chen, Weiming Liu, Yuhang Wang, Yihao Wang, Zheqi Lv, Xiaolin Zheng, Jianwei Yin
2025 J jnl
IEEE Trans. Serv. Comput.
Yuyuan Li, Yizhao Zhang, Weiming Liu, Xiaohua Feng, Zhongxuan Han, Chaochao Chen, Chenggang Yan
2025 J jnl
Sci. China Inf. Sci.
Fan Wang, Xuyun Zhang, Weiming Liu, Li Li, Yuwen Liu, Zhongyuan Zhang, Guanfeng Liu, Shengye Pang, Xiaolong Xu, Lianyong Qi
2025 J jnl
CoRR
Jiajie Su, Zihan Nan, Yunshan Ma, Xiaobo Xia, Xiaohua Feng, Weiming Liu, Xiaolin Zheng, Chaochao Chen
2025 J jnl
IEEE Trans. Consumer Electron.
Fan Wang, Weiming Liu, Chaochao Chen, Renwu Geng, Lianyong Qi, Xiaolin Zheng
2025 A* conf
IJCAI
Yuwen Liu, Lianyong Qi, Xingyuan Mao, Weiming Liu, Shichao Pei, Fan Wang, Xuyun Zhang, Amin Beheshti, Xiaokang Zhou
2024 J jnl
IEEE Trans. Multim.
Zhenghong Lin, Qishan Yan, Weiming Liu, Shiping Wang, Menghan Wang, Yanchao Tan, Carl Yang
2024 A* conf
KDD
Fan Wang, Chaochao Chen, Weiming Liu, Tianhao Fan, Xinting Liao, Yanchao Tan, Lianyong Qi, Xiaolin Zheng
2024 A* conf
IJCAI
Lianyong Qi, Yuwen Liu, Weiming Liu, Shichao Pei, Xiaolong Xu, Xuyun Zhang, Yingjie Wang, Wanchun Dou
2024 A* conf
IJCAI
Zhenghong Lin, Wei Huang, Hengyu Zhang, Jiayu Xu, Weiming Liu, Xinting Liao, Fan Wang, Shiping Wang, Yanchao Tan
2024 conf
WWW (Companion Volume)
Yanchao Tan, Hengyu Zhang, Zihao Zhou, Guofang Ma, Fan Wang, Weiming Liu, Xinting Liao, Vicki Stover Hertzberg, Carl Yang
2024 A* conf
NeurIPS
Xinting Liao, Weiming Liu, Pengyang Zhou, Fengyuan Yu, Jiahe Xu, Jun Wang, Wenjie Wang, Chaochao Chen, Xiaolin Zheng
2024 J jnl
CoRR
Xinting Liao, Weiming Liu, Pengyang Zhou, Fengyuan Yu, Jiahe Xu, Jun Wang, Wenjie Wang, Chaochao Chen, Xiaolin Zheng
2024 conf
WWW (Companion Volume)
Yuwen Liu, Lianyong Qi, Weiming Liu, Xiaolong Xu, Xuyun Zhang, Wanchun Dou
2024 A* conf
ACM Multimedia
Jun Dan, Weiming Liu, Mushui Liu, Chunfeng Xie, Shunjie Dong, Guofang Ma, Yanchao Tan, Jiazheng Xing
2024 A conf
ICME
Yanchao Tan, Zhenghong Lin, Sujie Pan, Siying Xu, Weiming Liu, Guofang Ma, Shiping Wang
2024 A* conf
AAAI
Zhongxuan Han, Chaochao Chen, Xiaolin Zheng, Meng Li, Weiming Liu, Binhui Yao, Yuyuan Li, Jianwei Yin
2024 A* conf
AAAI
Weiming Liu, Chaochao Chen, Xinting Liao, Mengling Hu, Yanchao Tan, Fan Wang, Xiaolin Zheng, Yew Soon Ong
2024 A* conf
ICDE
Yanchao Tan, Hang Lv, Zihao Zhou, Wenzhong Guo, Bo Xiong, Weiming Liu, Chaochao Chen, Shiping Wang, Carl Yang
2024 J jnl
IEEE Trans. Knowl. Data Eng.
Xiaolin Zheng, Weiming Liu, Chaochao Chen, Jiajie Su, Xinting Liao, Mengling Hu, Yanchao Tan
2024 J jnl
CoRR
Yingrong Wang, Anpeng Wu, Haoxuan Li, Weiming Liu, Qiaowei Miao, Ruoxuan Xiong, Fei Wu, Kun Kuang
2024 J jnl
CoRR
Jiajie Su, Chaochao Chen, Zibin Lin, Xi Li, Weiming Liu, Xiaolin Zheng
2024 A* conf
ICML
Weiming Liu, Xiaolin Zheng, Chaochao Chen, Jiahe Xu, Xinting Liao, Fan Wang, Yanchao Tan, Yew-Soon Ong
2024 A* conf
CVPR
Xinting Liao, Weiming Liu, Chaochao Chen, Pengyang Zhou, Fengyuan Yu, Huabin Zhu, Binhui Yao, Tao Wang, Xiaolin Zheng, Yanchao Tan
2024 J jnl
CoRR
Xinting Liao, Weiming Liu, Chaochao Chen, Pengyang Zhou, Fengyuan Yu, Huabin Zhu, Binhui Yao, Tao Wang, Xiaolin Zheng, Yanchao Tan
2024 A* conf
SIGIR
Jiajie Su, Chaochao Chen, Weiming Liu, Zibin Lin, Shuheng Shen, Weiqiang Wang, Xiaolin Zheng
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Shukai Wu, Xiao Yan, Weiming Liu, Shuchang Xu, Sanyuan Zhang
2024 A* conf
NeurIPS
Jun Dan, Weiming Liu, Chunfeng Xie, Hua Yu, Shunjie Dong, Yanchao Tan
2024 A* conf
ACM Multimedia
Hua Yu, Weiming Liu, Jiapeng Bai, Xu Gui, Yaqing Hou, Yew-Soon Ong, Qiang Zhang
2024 A* conf
WWW
Weiming Liu, Chaochao Chen, Xinting Liao, Mengling Hu, Jiajie Su, Yanchao Tan, Fan Wang
2023 A* conf
ACM Multimedia
Zhenghong Lin, Yanchao Tan, Yunfei Zhan, Weiming Liu, Fan Wang, Chaochao Chen, Shiping Wang, Carl Yang
2023 J jnl
IEEE Trans. Knowl. Data Eng.
Weiming Liu, Xiaolin Zheng, Jiajie Su, Longfei Zheng, Chaochao Chen, Mengling Hu
2023 A* conf
ACM Multimedia
Weiming Liu, Xiaolin Zheng, Chaochao Chen, Mengling Hu, Xinting Liao, Fan Wang, Yanchao Tan, Dan Meng, Jun Wang
2023 A* conf
WWW
Jiajie Su, Chaochao Chen, Weiming Liu, Fei Wu, Xiaolin Zheng, Haoming Lyu
2023 A* conf
ICDM
Yanchao Tan, Zihao Zhou, Leisheng Yu, Weiming Liu, Chaochao Chen, Guofang Ma, Xiao Hu, Vicki Stover Hertzberg, Carl Yang
2023 J jnl
CoRR
Mengling Hu, Chaochao Chen, Weiming Liu, Xinting Liao, Xiaolin Zheng
2023 A* conf
IJCAI
Weiming Liu, Chaochao Chen, Xinting Liao, Mengling Hu, Jianwei Yin, Yanchao Tan, Longfei Zheng
2023 A* conf
ACM Multimedia
Shukai Wu, Yuhang Yang, Shuchang Xu, Weiming Liu, Xiao Yan, Sanyuan Zhang
2023 A* conf
IJCAI
Xinting Liao, Weiming Liu, Chaochao Chen, Pengyang Zhou, Huabin Zhu, Yanchao Tan, Jun Wang, Yue Qi
2023 J jnl
CoRR
Xinting Liao, Weiming Liu, Chaochao Chen, Pengyang Zhou, Huabin Zhu, Yanchao Tan, Jun Wang, Yue Qi
2023 A* conf
ACM Multimedia
Zhongxuan Han, Chaochao Chen, Xiaolin Zheng, Weiming Liu, Jun Wang, Wenjie Cheng, Yuyuan Li
2023 J jnl
CoRR
Zhongxuan Han, Chaochao Chen, Xiaolin Zheng, Weiming Liu, Jun Wang, Wenjie Cheng, Yuyuan Li
2023 A* conf
WWW
Weiming Liu, Xiaolin Zheng, Chaochao Chen, Jiajie Su, Xinting Liao, Mengling Hu, Yanchao Tan
2023 A* conf
ACM Multimedia
Xinting Liao, Chaochao Chen, Weiming Liu, Pengyang Zhou, Huabin Zhu, Shuheng Shen, Weiqiang Wang, Mengling Hu, Yanchao Tan, Xiaolin Zheng
2023 J jnl
CoRR
Xinting Liao, Chaochao Chen, Weiming Liu, Pengyang Zhou, Huabin Zhu, Shuheng Shen, Weiqiang Wang, Mengling Hu, Yanchao Tan, Xiaolin Zheng
2023 J jnl
CoRR
Mengling Hu, Chaochao Chen, Weiming Liu, Xinyi Zhang, Xinting Liao, Xiaolin Zheng
2023 A* conf
NeurIPS
Hao Wang, Jiajun Fan, Zhichao Chen, Haoxuan Li, Weiming Liu, Tianqiao Liu, Quanyu Dai, Yichao Wang, Zhenhua Dong, Ruiming Tang
2023 J jnl
CoRR
Hao Wang, Zhichao Chen, Jiajun Fan, Haoxuan Li, Tianqiao Liu, Weiming Liu, Quanyu Dai, Yichao Wang, Zhenhua Dong, Ruiming Tang
2023 A* conf
AAAI
Xinting Liao, Weiming Liu, Xiaolin Zheng, Binhui Yao, Chaochao Chen
2023 J jnl
CoRR
Xinting Liao, Weiming Liu, Xiaolin Zheng, Binhui Yao, Chaochao Chen
2023 A* conf
ACM Multimedia
Jiajie Su, Chaochao Chen, Zibin Lin, Xi Li, Weiming Liu, Xiaolin Zheng
2023 conf
ACL (1)
Xiaolin Zheng, Mengling Hu, Weiming Liu, Chaochao Chen, Xinting Liao
2023 J jnl
CoRR
Xiaolin Zheng, Mengling Hu, Weiming Liu, Chaochao Chen, Xinting Liao
2023 A* conf
NeurIPS
Yuyuan Li, Chaochao Chen, Yizhao Zhang, Weiming Liu, Lingjuan Lyu, Xiaolin Zheng, Dan Meng, Jun Wang
2023 A* conf
NeurIPS
Yanchao Tan, Zihao Zhou, Hang Lv, Weiming Liu, Carl Yang
2022 A* conf
WWW
Weiming Liu, Xiaolin Zheng, Mengling Hu, Chaochao Chen
2022 J jnl
CoRR
Weiming Liu, Xiaolin Zheng, Mengling Hu, Chaochao Chen
2022 A* conf
ACM Multimedia
Xiaolin Zheng, Jiajie Su, Weiming Liu, Chaochao Chen
2022 J jnl
CoRR
Xiaolin Zheng, Jiajie Su, Weiming Liu, Chaochao Chen
2022 J jnl
CoRR
Hao Wang, Zhichao Chen, Jiajun Fan, Yuxin Huang, Weiming Liu, Xinggao Liu
2022 A* conf
SIGIR
Weiming Liu, Xiaolin Zheng, Jiajie Su, Mengling Hu, Yanchao Tan, Chaochao Chen
2022 J jnl
CoRR
Weiming Liu, Xiaolin Zheng, Mengling Hu, Chaochao Chen
2022 A* conf
IJCAI
Fan Wang, Weiming Liu, Chaochao Chen, Mengying Zhu, Xiaolin Zheng
2022 J jnl
CoRR
Fan Wang, Weiming Liu, Chaochao Chen, Mengying Zhu, Xiaolin Zheng
2022 A* conf
SIGIR
Yanchao Tan, Carl Yang, Xiangyu Wei, Chaochao Chen, Weiming Liu, Longfei Li, Jun Zhou, Xiaolin Zheng
2022 conf
DL4SR@CIKM
Yanchao Tan, Carl Yang, Xiangyu Wei, Ziyue Wu, Weiming Liu, Xiaolin Zheng
2022 J jnl
Neurocomputing
Shukai Wu, Weiming Liu, Qingqin Wang, Sanyuan Zhang, Zhenjie Hong, Shuchang Xu
2021 A* conf
NeurIPS
Weiming Liu, Jiajie Su, Chaochao Chen, Xiaolin Zheng
tests/unit/test_apk_cfg_features.py
← Index tests/unit/test_apk_cfg_features.py python
"""
Unit tests for APK CFG feature parity with the Binary Ninja pipeline.

Tests advanced CFG features computed from smali (topology hash, MD-index,
WL-MinHash, prime product, packed adjacency, block features export) and
the slimmed similarity table.

All tests use mocked smali input — no JADX/apktool/Java required.
"""
import pytest

from redb.extractors.decompiler.apk.smali_cfg import (
    SmaliCFGMetrics,
    compute_cfg_metrics,
)
from redb.extractors.decompiler.apk.method_extractor import (
    SMALI_OP_PRIMES,
    compute_prime_product_smali,
    count_call_instructions,
)

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


# ===================================================================
# Sample smali bodies for testing
# ===================================================================

# Simple linear method: 3 instructions, 1 block
SMALI_LINEAR = """\
    const/4 v0, 0x0
    invoke-virtual {p0, v0}, Lcom/Foo;->bar(I)V
    return-void
"""

# Diamond CFG: if-else with two paths merging
SMALI_DIAMOND = """\
    const/4 v0, 0x1
    if-eqz v0, :cond_0
    invoke-virtual {p0}, Lcom/Foo;->pathA()V
    goto :goto_0
    :cond_0
    invoke-virtual {p0}, Lcom/Foo;->pathB()V
    :goto_0
    return-void
"""

# Loop: a back edge from goto to a label before it
SMALI_LOOP = """\
    const/4 v0, 0x0
    :loop_start
    add-int/lit8 v0, v0, 0x1
    if-lt v0, v1, :loop_start
    return-void
"""

# Multi-block with several invoke calls
SMALI_MULTI_CALL = """\
    invoke-virtual {p0}, Lcom/Foo;->a()V
    invoke-static {v0}, Lcom/Bar;->b(I)V
    invoke-direct {p0, v1}, Lcom/Baz;-><init>(I)V
    const/4 v0, 0x0
    return-void
"""


# ===================================================================
# TestSmaliCFGMetricsAdvanced — new fields in SmaliCFGMetrics
# ===================================================================

class TestSmaliCFGMetricsAdvanced:
    """Test that advanced CFG fields are populated by compute_cfg_metrics."""

    def test_topology_hash_is_bytes(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert isinstance(m.cfg_topology_hash, bytes)
        assert len(m.cfg_topology_hash) == 16

    def test_topology_hash_nonzero_for_multiblock(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert m.cfg_topology_hash != b'\x00' * 16

    def test_topology_hash_zero_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.cfg_topology_hash == b'\x00' * 16

    def test_identical_cfg_same_topology_hash(self):
        """Two smali methods with the same CFG structure produce the same hash."""
        smali_a = """\
    const/4 v0, 0x1
    if-eqz v0, :cond_0
    const/4 v1, 0x2
    goto :goto_0
    :cond_0
    const/4 v1, 0x3
    :goto_0
    return-void
"""
        smali_b = """\
    const/4 v5, 0x9
    if-nez v5, :cond_0
    add-int v6, v5, v5
    goto :goto_0
    :cond_0
    sub-int v6, v5, v5
    :goto_0
    return-void
"""
        m_a = compute_cfg_metrics(smali_a)
        m_b = compute_cfg_metrics(smali_b)
        assert m_a.cfg_topology_hash == m_b.cfg_topology_hash

    def test_different_cfg_different_topology_hash(self):
        m_linear = compute_cfg_metrics(SMALI_LINEAR)
        m_diamond = compute_cfg_metrics(SMALI_DIAMOND)
        assert m_linear.cfg_topology_hash != m_diamond.cfg_topology_hash

    def test_md_index_topdown_nonzero(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert m.md_index_topdown != 0

    def test_md_index_bottomup_nonzero(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert m.md_index_bottomup != 0

    def test_md_index_zero_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.md_index_topdown == 0
        assert m.md_index_bottomup == 0

    def test_wl_minhash_length(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert len(m.wl_minhash) == 128

    def test_wl_minhash_sentinel_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.wl_minhash == [255] * 128

    def test_wl_minhash_values_are_uint8(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        for val in m.wl_minhash:
            assert 0 <= val <= 255

    def test_cfg_adjacency_nonempty_for_multiblock(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert len(m.cfg_adjacency) > 0

    def test_cfg_adjacency_empty_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.cfg_adjacency == []

    def test_cfg_adjacency_packed_format(self):
        """Each entry should be (src << 16) | tgt."""
        m = compute_cfg_metrics(SMALI_DIAMOND)
        for edge in m.cfg_adjacency:
            assert isinstance(edge, int)
            src = edge >> 16
            tgt = edge & 0xFFFF
            assert src < m.block_count
            assert tgt < m.block_count

    def test_block_features_exported(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert len(m.block_features) == m.block_count
        for bf in m.block_features:
            assert len(bf) == 8  # 7 categories + successor_count

    def test_cfg_feature_tlsh_none_for_small(self):
        """Small methods produce None (< 50 bytes of feature data)."""
        m = compute_cfg_metrics(SMALI_LINEAR)
        # Single-block linear method — too small for TLSH
        assert m.cfg_feature_tlsh is None

    def test_loop_count_with_back_edge(self):
        m = compute_cfg_metrics(SMALI_LOOP)
        assert m.loop_count >= 1


# ===================================================================
# TestPrimeProductSmali
# ===================================================================

class TestPrimeProductSmali:

    def test_empty_returns_zero(self):
        assert compute_prime_product_smali("") == 0

    def test_none_returns_zero(self):
        assert compute_prime_product_smali(None) == 0

    def test_known_computation(self):
        """Single invoke instruction → CALL category → prime 17."""
        smali = "    invoke-virtual {p0}, Lcom/Foo;->bar()V"
        assert compute_prime_product_smali(smali) == 17

    def test_two_instructions(self):
        """const (CONST→2) * invoke (CALL→17) = 34."""
        smali = """\
    const/4 v0, 0x0
    invoke-virtual {p0, v0}, Lcom/Foo;->bar(I)V
"""
        assert compute_prime_product_smali(smali) == 2 * 17

    def test_skips_directives_and_labels(self):
        """Directives, labels, and comments should be skipped."""
        smali = """\
.registers 2
.line 10
    :label
    # comment
    const/4 v0, 0x0
"""
        # Only const/4 → CONST → prime 2
        assert compute_prime_product_smali(smali) == 2

    def test_position_independent(self):
        """Reordering instructions produces the same product (multiplication is commutative)."""
        smali_a = """\
    add-int v0, v1, v2
    invoke-virtual {p0}, Lcom/Foo;->bar()V
"""
        smali_b = """\
    invoke-virtual {p0}, Lcom/Foo;->bar()V
    add-int v0, v1, v2
"""
        assert compute_prime_product_smali(smali_a) == compute_prime_product_smali(smali_b)

    def test_all_categories_have_primes(self):
        """Every category in SMALI_OP_PRIMES is a positive integer."""
        for cat, prime in SMALI_OP_PRIMES.items():
            assert isinstance(prime, int)
            assert prime >= 1

    def test_mod_2_64(self):
        """Result should be mod 2^64 (doesn't overflow)."""
        # A very long method — product stays within uint64
        smali = "\n".join(["    mul-int v0, v1, v2"] * 1000)
        result = compute_prime_product_smali(smali)
        assert 0 <= result < 2**64


# ===================================================================
# TestCallCount
# ===================================================================

class TestCallCount:

    def test_empty(self):
        assert count_call_instructions("") == 0

    def test_none(self):
        assert count_call_instructions(None) == 0

    def test_single_invoke(self):
        smali = "    invoke-virtual {p0}, Lcom/Foo;->bar()V"
        assert count_call_instructions(smali) == 1

    def test_multiple_invoke_types(self):
        assert count_call_instructions(SMALI_MULTI_CALL) == 3

    def test_non_invoke_not_counted(self):
        smali = """\
    const/4 v0, 0x0
    add-int v1, v0, v0
    return-void
"""
        assert count_call_instructions(smali) == 0


# ===================================================================
# TestSimilarityTableSlimmed
# ===================================================================

class TestSimilarityTableSlimmed:
    """Verify the similarity table no longer contains moved fields."""

    def test_export_similarity_no_block_count(self):
        """block_count should not be in similarity export columns."""
        from redb.extractors.decompiler.DecompileAPK import DecompileAPK
        from unittest.mock import MagicMock

        extractor = DecompileAPK.__new__(DecompileAPK)
        extractor.log = MagicMock()
        extractor.sha256 = "a" * 64
        extractor.sha1 = "b" * 40
        extractor.md5 = "c" * 32
        extractor.analysis_results = {
            "sha256": "a" * 64,
            "sha1": "b" * 40,
            "md5": "c" * 32,
            "similarity_metrics": [{
                "smali_method_hash": "d" * 64,
                "cyclomatic_complexity": 3,
                "ssdeep_smali": None,
                "tlsh_smali": None,
                "minhash": [1, 2, 3],
            }],
        }

        export = extractor.prepare_export_data("ClickHouseExporter")
        sim_cols = export["method_similarity_metrics"]["column_names"]
        assert "block_count" not in sim_cols
        assert "edge_count" not in sim_cols
        assert "loop_count" not in sim_cols
        assert "max_depth" not in sim_cols
        assert "max_fan_out" not in sim_cols
        # These should still be there
        assert "smali_method_hash" in sim_cols
        assert "ssdeep_smali" in sim_cols
        assert "minhash" in sim_cols
        # cyclomatic_complexity moved to cfg table
        assert "cyclomatic_complexity" not in sim_cols


# ===================================================================
# TestCFGTableExport
# ===================================================================

class TestCFGTableExport:
    """Verify the new CFG table is exported correctly."""

    def test_export_cfg_table_present(self):
        from redb.extractors.decompiler.DecompileAPK import DecompileAPK
        from unittest.mock import MagicMock

        extractor = DecompileAPK.__new__(DecompileAPK)
        extractor.log = MagicMock()
        extractor.analysis_results = {
            "sha256": "a" * 64,
            "sha1": "b" * 40,
            "md5": "c" * 32,
            "cfg": [{
                "smali_method_hash": "d" * 64,
                "cfg_topology_hash": b'\x01' * 16,
                "block_count": 4,
                "edge_count": 5,
                "instructions_count": 20,
                "call_count": 3,
                "cyclomatic_complexity": 3,
                "loop_count": 1,
                "max_depth": 2,
                "max_fan_out": 2,
                "md_index_topdown": 12345,
                "md_index_bottomup": 67890,
                "prime_product_smali": 999,
                "cfg_feature_tlsh": None,
                "wl_minhash": [0] * 128,
                "bb_features": [[10, 1, 0, 2, 1, 0, 0, 2]] * 4,
                "cfg_adjacency": [0x00010000, 0x00010002],
            }],
        }

        export = extractor.prepare_export_data("ClickHouseExporter")
        assert "cfg_methods" in export
        cfg_export = export["cfg_methods"]
        assert cfg_export["table"] == "code_apk_cfg_methods"
        assert len(cfg_export["data"]) == 1
        assert "cfg_topology_hash" in cfg_export["column_names"]
        assert "prime_product_smali" in cfg_export["column_names"]
        assert "wl_minhash" in cfg_export["column_names"]
        assert "bb_features" in cfg_export["column_names"]
        assert "cfg_adjacency" in cfg_export["column_names"]
        # Verify column count matches data width
        assert len(cfg_export["column_names"]) == len(cfg_export["data"][0])
        assert len(cfg_export["column_type_names"]) == len(cfg_export["data"][0])