Hai Lin

130 papers A* 6A 4B 6C 7Misc 2Journal 71Unranked 32
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Shaoxiong Zhan, Yanlin Lai, Zheng Liu, Hai Lin, Shen Li, Xiaodong Cai, Zijian Lin, Wen Huang, Hai-Tao Zheng
2026 A* conf
AAAI
Peng Zhang, Wanggui He, Mushui Liu, Wenyi Xiao, Siyu Zou, Yuan Li, Xingjian Wang, Guanghao Zhang, Yanpeng Liu, Weilong Dai, Jinlong Liu, Shuyi Ying, Ruikai Zhou, Yunlong Yu, Yubo Tao, Hai Lin, Hao Jiang
2026 J jnl
IEEE Trans. Cogn. Commun. Netw.
Ning Yang, Xin Yuan, Hai Lin, Haijun Zhang, Pin Lv, Jun Wang
2026 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Jianhui Wang, Jiarui Liu, Zikai Hu, Hai Lin, Kairui Chen, Dachang Zhu
2026 J jnl
CoRR
Bukunmi Gabriel Odunlami, Marcos Netto, Hai Lin
2026 J jnl
CoRR
Shunlong Wu, Hai Lin, Shaoshen Chen, Tingwei Lu, Yongqin Zeng, Shaoxiong Zhan, Hai-Tao Zheng, Hong-Gee Kim
2025 conf
SPAWC
Hai Lin
2025 J jnl
CoRR
Hai Lin
2025 A* conf
CVPR
Yankai Jiang, Peng Zhang, Donglin Yang, Yuan Tian, Hai Lin, Xiaosong Wang
2025 J jnl
CoRR
Yankai Jiang, Peng Zhang, Donglin Yang, Yuan Tian, Hai Lin, Xiaosong Wang
2025 J jnl
CoRR
Xiaodong Cai, Hai Lin, Shaoxiong Zhan, Weiqi Luo, Hong-Gee Kim, Hongyan Hao, Yu Yang, Hai-Tao Zheng
2025 J jnl
BMC Medical Imaging
Tong-Xing Wang, Xiao-Bin Huang, Tong Fu, Yu-Jia Gao, Di Zhang, Lin-Dong Liu, Ya-Mei Zhang, Hai Lin, Jian-Min Yuan, Cun-Nan Mao, Xin-Ying Wu
2025 A conf
ICME
Haiyang Liu, Shaojian Qiu, Hai Lin, Yingjie Kuang, Shunpeng Li
2025 J jnl
IEEE Trans Autom. Sci. Eng.
Qihan Qi, Hai Lin, Xinsong Yang, Yaping Sun, Xingxing Ju, Wenwu Yu
2025 conf
BIBM
Peng Zhang, Zhenhao Peng, Yuan Li, Hanxiao Huang, Bin Zhang, Haotian Song, Meng Geng, Yubo Tao, Hai Lin
2025 Misc conf
ICASSP
Zixuan Xiong, Hai Lin, Lichen Bai, Yinghui Li, Hai-Tao Zheng, Hong-Gee Kim
2025 J jnl
IEEE Trans. Cybern.
Hai Lin, Xinsong Yang, Guanghui Wen, Weixing Zheng
2025 A* conf
AAAI
Lichen Bai, Zixuan Xiong, Hai Lin, Guangwei Xu, Xiangjin Xie, Ruijie Guo, Zhanhui Kang, Haitao Zheng, Hong-Gee Kim
2025 conf
NLPCC (4)
Hai Lin, Shaoxiong Zhan, Junyou Su, Hai-Tao Zheng, Hui Wang, Xin Su, Ruitong Liu
2025 conf
VTC2025-Fall
Yusuke Sato, Yi-Han Chiang, Hai Lin
2025 J jnl
J. Web Eng.
Guoxin Han, Hai Lin, Genchao Yan, Kaiye Dai
2025 A conf
ECAI
Shaoxiong Zhan, Hai Lin, Hongming Tan, Xiaodong Cai, Hai-Tao Zheng, Xin Su, Zifei Shan, Ruitong Liu, Hong-Gee Kim
2025 J jnl
CoRR
Shaoxiong Zhan, Hai Lin, Hongming Tan, Xiaodong Cai, Hai-Tao Zheng, Xin Su, Zifei Shan, Ruitong Liu, Hong-Gee Kim
2025 J jnl
IEEE Access
Hai Lin, Ji Wang, Jingguo Li
2025 J jnl
Trans. Inst. Meas. Control
Gang Zhang, Deqiang Cheng, Zhiyong Weng, Hai Lin
2025 J jnl
IEEE Trans. Knowl. Data Eng.
Hongming Tan, Shaoxiong Zhan, Hai Lin, Hai-Tao Zheng, Wai Kin Chan
2025 J jnl
Briefings Bioinform.
Zhilong Liu, Hai Lin, Xiang Li, Hao Xue, Yuer Lu, Fei Xu, Jianwei Shuai
2025 J jnl
CoRR
Ning Yang, Hai Lin, Yibo Liu, Baoliang Tian, Guoqing Liu, Haijun Zhang
2025 C conf
ACC
Fahimeh Orvati Nia, Hai Lin
2025 J jnl
CoRR
Fahimeh Orvati Nia, Hai Lin
2025 J jnl
Multim. Tools Appl.
Yifan Hu, Xi Huang, Xianbing Wang, Hai Lin, Rong Zhang
2025 J jnl
Displays
Xiaoqing Pei, Miao Yan, Yifan Liu, Lin Fan, Tao Jiang, Zibo Mi, Lina Liu, Chun Li, Hai Lin, Shasha Li, Weiling Yang, Fanming Zeng, Zhongmin Su
2025 A* conf
CCS
Hai Lin, Chenglong Li, Jiahai Yang, Zhiliang Wang, Jiaqi Bai
2024 J jnl
BMC Medical Imaging
Min Duan, Rongrong Pan, Qing Gao, Xinying Wu, Hai Lin, Jianmin Yuan, Yamei Zhang, Lindong Liu, Youyong Tian, Tong Fu
2024 Misc conf
ICASSP
Yun Liang, Hai Lin, Shaojian Qiu, Yihang Zhang
2024 J jnl
CoRR
Yun Liang, Hai Lin, Shaojian Qiu, Yihang Zhang
2024 J jnl
CoRR
Hai Lin, Cheng Huang, Zhihong Chen
2024 J jnl
CoRR
Federico Ottomano, John Yannis Goulermas, Vladimir V. Gusev, Rahul Savani, Michael W. Gaultois, Troy D. Manning, Hai Lin, Teresa P. Manzanera, Emmeline G. Poole, Matthew S. Dyer, John B. Claridge, Jon Alaria, Luke M. Daniels, Su Varma, David Rimmer, Kevin Sanderson, Matthew J. Rosseinsky
2024 J jnl
SIAM J. Imaging Sci.
Qi Zhang, Chenglong Bao, Hai Lin, Mingxu Hu
2024 A* conf
NDSS
Hai Lin, Chenglong Li, Jiahai Yang, Zhiliang Wang, Linna Fan, Chenxin Duan
2024 J jnl
IEEE Trans. Mob. Comput.
Yan Peng, Xiaogang Tang, Yiqing Zhou, Jin-Tao Li, Yanli Qi, Ling Liu, Hai Lin
2024 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Hai Lin, Jin Liu, Xingye Li, Lai Wei, Yuxin Liu, Bing Han, Zhongdai Wu
2024 B conf
PacificVis
Keyue Xu, Jiapu Zhao, Yubo Tao, Hai Lin
2024 J jnl
J. Vis.
Yinzhao Wang, Yuan Li, Yubo Tao, Hai Lin, Jiarun Wang
2024 J jnl
J. Frankl. Inst.
Yongzhuang Liu, Yang Song, Hai Lin
2024 A conf
ICME
Yihang Zhang, Yun Liang, Shitong Weng, Hai Lin, Liping Chen, Shenlong Zheng
2024 J jnl
CoRR
Hai Lin, Shaoxiong Zhan, Junyou Su, Haitao Zheng, Hui Wang
2024 J jnl
IET Image Process.
Hai Lin, Junjie Yang
2024 J jnl
IEEE Trans. Dependable Secur. Comput.
Chenxin Duan, Sainan Li, Hai Lin, Wenqi Chen, Guanglei Song, Chenglong Li, Jiahai Yang, Zhiliang Wang
2024 J jnl
Appl. Artif. Intell.
Zhengmeng Xu, Hai Lin, Yufeng Chen, Yanli Li
2024 A* conf
HPCA
Jiexiong Xu, Yiquan Chen, Yijing Wang, Wenhui Shi, Guoju Fang, Yi Chen, Huasheng Liao, Yang Wang, Hai Lin, Zhen Jin, Qiang Liu, Wenzhi Chen
2024 B conf
WCNC
Yuchen Lei, Kai Jiang, Zhenning Wang, Yue Cao, Hai Lin, Liang Chen
2024 conf
NAACL-HLT (Findings)
Yuxuan Kuang, Hai Lin, Meng Jiang
2024 J jnl
Inf. Sci.
Yan Song, Hai Lin, Zhaowen Li
2024 J jnl
CoRR
Jiwei Tang, Jin Xu, Tingwei Lu, Hai Lin, Yiming Zhao, Hai-Tao Zheng
2024 J jnl
CoRR
Hongming Tan, Shaoxiong Zhan, Hai Lin, Hai-Tao Zheng, Wai Kin Chan
2024 J jnl
IET Image Process.
Yixuan Xu, Xianbing Wang, Hua Zhang, Hai Lin
2024 J jnl
Memetic Comput.
Shifan Xu, Zhibin Xu, Jiannan Zheng, Hai Lin, Liang Zou, Meng Lei
2024 J jnl
Briefings Bioinform.
Fei Xu, Huan Hu, Hai Lin, Jun Lu, Feng Cheng, Jiqian Zhang, Xiang Li, Jianwei Shuai
2023 J jnl
Remote. Sens.
Hai Lin, Jie Wang, Zhenhua Chen, Junxiang Ge
2023 J jnl
Sensors
Hai Lin, Jie Wang, Junxiang Ge
2023 J jnl
Int. J. Inf. Technol. Web Eng.
Zhengmeng Xu, Hai Lin, Meiping Wu
2023 J jnl
Comput. Biol. Medicine
Huan Hu, Zhen Feng, Hai Lin, Jinyan Cheng, Jie Lyu, Yaru Zhang, Junjie Zhao, Fei Xu, Tao Lin, Qi Zhao, Jianwei Shuai
2023 J jnl
IEEE Trans. Wirel. Commun.
Bule Sun, Xiaogang Tang, Yiqing Zhou, Zhengang Pan, Hai Lin
2023 J jnl
IEEE Trans. Wirel. Commun.
Yan Peng, Xiaogang Tang, Yiqing Zhou, Yuenan Hou, Jintao Li, Yanli Qi, Ling Liu, Hai Lin
2023 J jnl
IEEE Access
Siyang Chen, Tuoheti Reheman, Chaolun Li, Xichun Wu, Hai Lin, Zhuochen Lin, Xudong Liang, Haiyan Li, Jinxin Zhang
2023 J jnl
Briefings Bioinform.
Huan Hu, Zhen Feng, Hai Lin, Junjie Zhao, Yaru Zhang, Fei Xu, Lingling Chen, Feng Chen, Yunlong Ma, Jianzhong Su, Qi Zhao, Jianwei Shuai
2023 J jnl
Comput. Networks
Luyao Chen, Yong Tang, Jingwen Xia, Siyang Chen, Chengyu Zheng, Hai Lin, Wenyong Wang
2023 J jnl
Int. J. Gen. Syst.
Hai Lin, Zhaowen Li
2023 J jnl
CoRR
Zhengmeng Xu, Hai Lin
2023 J jnl
IEEE Trans. Smart Grid
Min Du, Xuan Liu, Zuyi Li, Hai Lin
2023 J jnl
J. Intell. Fuzzy Syst.
Jun Liang, Keyi Huang, Shaojian Qiu, Hai Lin, Keng Lian
2023 J jnl
Remote. Sens.
Hai Lin, Jie Wang, Junxiang Ge
2022 J jnl
Sci. China Inf. Sci.
Linxia Xiao, Caizi Li, Yanjiang Wang, Weixin Si, Hai Lin, Doudou Zhang, Xiaodong Cai, Pheng-Ann Heng
2022 conf
HCI (13)
Xi Xu, Hai Lin
2022 J jnl
IEEE Access
Jie Wang, Hai Lin, Fan Yang, Guangyang Xu, Junxiang Ge
2022 B conf
GLOBECOM
Liting Zhang, Hao Huan, Ran Tao, Yue Wang, Xiaogang Tang, Hai Lin
2022 J jnl
IET Image Process.
Hai Lin, Junjie Yang
2022 J jnl
Int. J. Pattern Recognit. Artif. Intell.
Lina Yang, Hai Lin, Wei Li, Zuqiang Meng, Patrick Shen-Pei Wang, Xichun Li, Huiwu Luo
2022 J jnl
J. Intell. Fuzzy Syst.
Dan Huang, Hai Lin, Zhaowen Li
2022 conf
ICCCS
Hai Lin, Xiaogang Tang, Binquan Zhang, Guangming Yuan, Haibin Li, Hang Lv
2022 J jnl
CoRR
Kevin Smith, Hai Lin, Praveen Tiwari, Marjorie Sayer, Claudionor Coelho
2022 conf
EITCE
Peng Sun, Hai Lin, Huailong Yu, You Zhong, Xiaoping Wu, Bing Sun
2021 conf
VTC Fall
Hai Lin, Bo Zhang, Yangjie Cao, Zhi Liu, Xianfu Chen
2021 conf
6GN
Yunyi Zhang, Ling Zhang, Tinghua Chen, Hai Lin, Shengke Ye, Jun Du, Tao Yu, Chuqiao Chen
2021 J jnl
Int. J. Comput. Assist. Radiol. Surg.
Linxia Xiao, Caizi Li, Yanjiang Wang, Weixin Si, Doudou Zhang, Hai Lin, Xiaodong Cai, Pheng-Ann Heng
2021 conf
CONF-CDS
Chen Chen, Lianglong Li, Hai Lin, Yang Wang, Shuai Yuan, Shan Chen
2021 conf
6GN
Hai Lin
2021 J jnl
IEEE Access
Hai Lin, Junjie Yang
2021 conf
ICAIT
Weiling Yang, Zhuang Leng, Xiliang Jiang, Ce Li, Hai Lin, Fanming Zeng, Chun Li, Zhongmin Su
2021 conf
WorldCIST (1)
Hai Lin, Lina Yang, Patrick Shen-Pei Wang
2019 conf
FSDM
Hai Lin, Yingjie Chen, Xuchu Jiang, Xinyong Mao
2019 J jnl
Comput. Ind. Eng.
Hongqi Liu, Hai Lin, Xuchu Jiang, Xinyong Mao, Quanxin Liu, Bin Li
2019 A conf
IROS
Martin Fevre, Hai Lin, James P. Schmiedeler
2018 conf
SmartWorld/SCALCOM/UIC/ATC/CBDCom/IOP/SCI
Weiping Zhu, Jiangbo Qin, Ruoshan Kong, Hai Lin, Zongjian He
2018 B conf
GLOBECOM
Jingyi Wang, Xinyue Zhang, Haijun Zhang, Hai Lin, Hideki Tode, Miao Pan, Zhu Han
2018 J jnl
Manag. Sci.
Hai Lin, Chunchi Wu, Guofu Zhou
2017 C conf
ICCC
Hai Lin, Rong Xie, Lanning Wei
2017 J jnl
计算机科学
Xibo Wang, Hongshuai Ge, Ruiquan Wang, Hai Lin
2016 C conf
ACC
Bohui Wang, Yingguan Wang, Bin Zhang, Fengrong Li, Jingcheng Wang, Hai Lin, Xiaocheng Li
2016 J jnl
Neurocomputing
Bohui Wang, Jingcheng Wang, Bin Zhang, Hai Lin, Xiaocheng Li, Hongyuan Wang
2016 C conf
IECON
Simin Jiang, Peng Ye, Guohua Jin, Yuke Qi, Hai Lin
2016 C conf
ACC
Xiaobin Zhang, Yinhao Zhu, Hai Lin
2016 J jnl
Inf. Sci.
Shuo Li, Zhengrong Xiang, Hai Lin, Hamid Reza Karimi
2015 conf
ICCVE
Li Wang, Sheng Tao, Hai Lin, Chunli Li, Wei Zhang, Liyong Liu
2015 C conf
ACC
Xiaobin Zhang, Hai Lin
2014 conf
CyberC
Hai Lin, Ping Chen, Lusheng Wang
2014 conf
BMSB
Hai Lin, Chao Zhang, Chang-Yong Pan
2013 conf
ICC
Yabo Li, Linlin Fan, Hai Lin, Minjian Zhao
2013 J jnl
IEEE Commun. Lett.
Michele Morelli, Marco Moretti, Hai Lin
2013 conf
CyberC
Lusheng Wang, Qingfeng Zhou, Hai Lin
2012 J jnl
ACM Trans. Design Autom. Electr. Syst.
Hai Lin, Tiansi Hu, Yunsi Fei
2012 J jnl
J. Softw.
Dajiang Lei, Qingsheng Zhu, Jun Chen, Hai Lin, Peng Yang
2011 conf
CAD/Graphics
Bangjie Tang, Zhiguang Zhou, Hai Lin
2011 conf
ICCA
Youyi Wang, Manuel Duarte-Mermoud, Hai Lin, Marcos E. Orchard
2009 conf
ROBIO
Hai Lin, Weisheng Yan, Mingfeng Li, Peng Wen, Chunhui Zhang, Mei Li
2009 C conf
ACC
Mohsen Zamani, Hai Lin
2009 conf
ROBIO
Weisheng Yan, Hai Lin, Ming Wang, Xiaochuan Li, Mei Li, Yintao Wang
2008 conf
CSSE (2)
Zunqi Yang, Hai Lin
2008 ch.
Innovative Techniques in Instruction Technology, E-learning, E-assessment, and Education
Hai Lin
2008 J jnl
IEEE Trans. Autom. Control.
Hai Lin
2008 ch.
Innovative Techniques in Instruction Technology, E-learning, E-assessment, and Education
Hai Lin, Zhenlong Zheng
2008 conf
CSSE (4)
Hai Lin, Xiaoping Chen
2008 B conf
SMC
Yang Yang, Hai Lin
2007 conf
IPC
Hai Lin, Yongxin Zhu, Hua Chen, Wei Guo
2006 conf
ICICIC (1)
Weihong Wang, Qu Li, Shanshan Han, Hai Lin
2006 conf
PATMOS
Hai Lin, Yu Wang, Rong Luo, Huazhong Yang, Hui Wang
2006 conf
ISQED
Yu Wang, Hai Lin, Huazhong Yang, Rong Luo, Hui Wang
2002 B conf
EDBT
Ouri Wolfson, Hu Cao, Hai Lin, Goce Trajcevski, Fengli Zhang, Naphtali Rishe
2002 conf
ICEIS
Goce Trajcevski, Ouri Wolfson, Hu Cao, Hai Lin, Fengli Zhang, Naphtali Rishe
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])