Nan Xue

87 papers A* 25A 1C 3Journal 54Unranked 4
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Zeran Ke, Bin Tan, Gui-Song Xia, Yujun Shen, Nan Xue
2026 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Ming Qian, Bin Tan, Qiuyu Wang, Xianwei Zheng, Hanjiang Xiong, Gui-Song Xia, Yujun Shen, Nan Xue
2025 J jnl
CoRR
Changkun Liu, Bin Tan, Zeran Ke, Shangzhan Zhang, Jiachen Liu, Ming Qian, Nan Xue, Yujun Shen, Tristan Braud
2025 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Zi-Ming Wang, Nan Xue, Ling Lei, Rebecka Jörnsten, Gui-Song Xia
2025 A* conf
CVPR
Bin Tan, Rui Yu, Yujun Shen, Nan Xue
2025 A* conf
CVPR
Zeran Ke, Bin Tan, Xianwei Zheng, Yujun Shen, Tianfu Wu, Nan Xue
2025 J jnl
CoRR
Zeran Ke, Bin Tan, Xianwei Zheng, Yujun Shen, Tianfu Wu, Nan Xue
2025 J jnl
CoRR
Ming Qian, Bin Tan, Qiuyu Wang, Xianwei Zheng, Hanjiang Xiong, Gui-Song Xia, Yujun Shen, Nan Xue
2024 A* conf
CVPR
Xianpeng Liu, Ce Zheng, Ming Qian, Nan Xue, Chen Chen, Zhebin Zhang, Chen Li, Tianfu Wu
2024 J jnl
CoRR
Xianpeng Liu, Ce Zheng, Ming Qian, Nan Xue, Chen Chen, Zhebin Zhang, Chen Li, Tianfu Wu
2024 A* conf
CVPR
Nan Xue, Bin Tan, Yuxi Xiao, Liang Dong, Gui-Song Xia, Tianfu Wu, Yujun Shen
2024 J jnl
CoRR
Zi-Ming Wang, Nan Xue, Ling Lei, Rebecka Jörnsten, Gui-Song Xia
2024 A* conf
AAAI
Jiakun Xu, Bowen Xu, Gui-Song Xia, Liang Dong, Nan Xue
2024 J jnl
CoRR
Bin Tan, Rui Yu, Yujun Shen, Nan Xue
2024 A* conf
CVPR
Han Feng, Wenchao Ma, Quankai Gao, Xianwei Zheng, Nan Xue, Huijuan Xu
2024 J jnl
CoRR
Han Feng, Wenchao Ma, Quankai Gao, Xianwei Zheng, Nan Xue, Huijuan Xu
2023 A* conf
NeurIPS
Lunhao Duan, Shanshan Zhao, Nan Xue, Mingming Gong, Gui-Song Xia, Dacheng Tao
2023 J jnl
CoRR
Lunhao Duan, Shanshan Zhao, Nan Xue, Mingming Gong, Gui-Song Xia, Dacheng Tao
2023 A conf
ICME
Yuxin Jin, Ming Qian, Jincheng Xiong, Nan Xue, Gui-Song Xia
2023 J jnl
CoRR
Yuxin Jin, Ming Qian, Jincheng Xiong, Nan Xue, Gui-Song Xia
2023 A* conf
CVPR
Jian Ding, Nan Xue, Gui-Song Xia, Bernt Schiele, Dengxin Dai
2023 J jnl
CoRR
Jian Ding, Nan Xue, Gui-Song Xia, Bernt Schiele, Dengxin Dai
2023 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Nan Xue, Tianfu Wu, Song Bai, Fu-Dong Wang, Gui-Song Xia, Liangpei Zhang, Philip H. S. Torr
2023 A* conf
CVPR
Yuxi Xiao, Nan Xue, Tianfu Wu, Gui-Song Xia
2023 A* conf
ICCV
Xianpeng Liu, Ce Zheng, Kelvin Cheng, Nan Xue, Guo-Jun Qi, Tianfu Wu
2023 J jnl
CoRR
Xianpeng Liu, Ce Zheng, Kelvin Cheng, Nan Xue, Guo-Jun Qi, Tianfu Wu
2023 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Bin Tan, Nan Xue, Tianfu Wu, Gui-Song Xia
2023 J jnl
CoRR
Jiakun Xu, Bowen Xu, Gui-Song Xia, Liang Dong, Nan Xue
2023 A* conf
ICCV
Ming Qian, Jincheng Xiong, Gui-Song Xia, Nan Xue
2023 J jnl
CoRR
Ming Qian, Jincheng Xiong, Gui-Song Xia, Nan Xue
2023 J jnl
CoRR
Nan Xue, Bin Tan, Yuxi Xiao, Liang Dong, Gui-Song Xia, Tianfu Wu
2022 J jnl
CoRR
Bowen Xu, Jiakun Xu, Nan Xue, Gui-Song Xia
2022 A* conf
CVPR
Jian Ding, Nan Xue, Gui-Song Xia, Dengxin Dai
2022 conf
3DV
Wenchao Ma, Bin Tan, Nan Xue, Tianfu Wu, Xianwei Zheng, Gui-Song Xia
2022 J jnl
CoRR
Wenchao Ma, Bin Tan, Nan Xue, Tianfu Wu, Xianwei Zheng, Gui-Song Xia
2022 J jnl
CoRR
Nan Xue, Tianfu Wu, Song Bai, Fu-Dong Wang, Gui-Song Xia, Liangpei Zhang, Philip H. S. Torr
2022 A* conf
AAAI
Xianpeng Liu, Nan Xue, Tianfu Wu
2022 A* conf
CVPR
Nan Xue, Tianfu Wu, Gui-Song Xia, Liangpei Zhang
2022 J jnl
CoRR
Yuxi Xiao, Nan Xue, Tianfu Wu, Gui-Song Xia
2022 J jnl
CoRR
Bin Tan, Nan Xue, Tianfu Wu, Gui-Song Xia
2022 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Jian Ding, Nan Xue, Gui-Song Xia, Xiang Bai, Wen Yang, Michael Ying Yang, Serge J. Belongie, Jiebo Luo, Mihai Datcu, Marcello Pelillo, Liangpei Zhang
2022 A* conf
ICLR
Ziming Wang, Nan Xue, Ling Lei, Gui-Song Xia
2022 J jnl
CoRR
Zi-Ming Wang, Nan Xue, Ling Lei, Gui-Song Xia
2022 A* conf
CVPR
Xiangwei Jiang, Rujiao Long, Nan Xue, Zhibo Yang, Cong Yao, Gui-Song Xia
2022 J jnl
CoRR
Xiangwei Jiang, Rujiao Long, Nan Xue, Zhibo Yang, Cong Yao, Gui-Song Xia
2022 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Linxi Huan, Nan Xue, Xianwei Zheng, Wei He, Jianya Gong, Gui-Song Xia
2021 J jnl
CoRR
Jian Ding, Nan Xue, Gui-Song Xia, Dengxin Dai
2021 A* conf
CVPR
Quankai Gao, Fudong Wang, Nan Xue, Jin-Gang Yu, Gui-Song Xia
2021 J jnl
CoRR
Quankai Gao, Fudong Wang, Nan Xue, Jin-Gang Yu, Gui-Song Xia
2021 conf
ICCVW
Gui-Song Xia, Jian Ding, Ming Qian, Nan Xue, Jiaming Han, Xiang Bai, Michael Ying Yang, Shengyang Li, Serge J. Belongie, Jiebo Luo, Mihai Datcu, Marcello Pelillo, Liangpei Zhang, Qiang Zhou, Chao-hui Yu, Kaixuan Hu, Yingjia Bu, Wenming Tan, Zhe Yang, Wei Li, Shang Liu, Jiaxuan Zhao, Tianzhi Ma, Zi-han Gao, Lingqi Wang, Yi Zuo, Licheng Jiao, Chang Meng, Hao Wang, Jiahao Wang, Yiming Hui, Zhuojun Dong, Jie Zhang, Qianyue Bao, Zixiao Zhang, Fang Liu
2021 J jnl
CoRR
Gui-Song Xia, Jian Ding, Ming Qian, Nan Xue, Jiaming Han, Xiang Bai, Michael Ying Yang, Shengyang Li, Serge J. Belongie, Jiebo Luo, Mihai Datcu, Marcello Pelillo, Liangpei Zhang, Qiang Zhou, Chao-hui Yu, Kaixuan Hu, Yingjia Bu, Wenming Tan, Zhe Yang, Wei Li, Shang Liu, Jiaxuan Zhao, Tianzhi Ma, Zi-han Gao, Lingqi Wang, Yi Zuo, Licheng Jiao, Chang Meng, Hao Wang, Jiahao Wang, Yiming Hui, Zhuojun Dong, Jie Zhang, Qianyue Bao, Zixiao Zhang, Fang Liu
2021 J jnl
CoRR
Xianpeng Liu, Nan Xue, Tianfu Wu
2021 J jnl
CoRR
Nan Xue, Tianfu Wu, Zhen Zhang, Gui-Song Xia
2021 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Nan Xue, Song Bai, Fu-Dong Wang, Gui-Song Xia, Tianfu Wu, Liangpei Zhang, Philip H. S. Torr
2021 J jnl
CoRR
Jian Ding, Nan Xue, Gui-Song Xia, Xiang Bai, Wen Yang, Michael Ying Yang, Serge J. Belongie, Jiebo Luo, Mihai Datcu, Marcello Pelillo, Liangpei Zhang
2021 A* conf
ICCV
Rujiao Long, Wen Wang, Nan Xue, Feiyu Gao, Zhibo Yang, Yongpan Wang, Gui-Song Xia
2021 J jnl
CoRR
Rujiao Long, Wen Wang, Nan Xue, Feiyu Gao, Zhibo Yang, Yongpan Wang, Gui-Song Xia
2021 A* conf
ICCV
Bin Tan, Nan Xue, Song Bai, Tianfu Wu, Gui-Song Xia
2021 J jnl
CoRR
Bin Tan, Nan Xue, Song Bai, Tianfu Wu, Gui-Song Xia
2021 A* conf
CVPR
Jiaming Han, Jian Ding, Nan Xue, Gui-Song Xia
2021 J jnl
CoRR
Jiaming Han, Jian Ding, Nan Xue, Gui-Song Xia
2021 conf
CDC
Nan Xue, Ulrich Münz, Zhihua Qu, Wei Sun
2020 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Fu-Dong Wang, Nan Xue, Yipeng Zhang, Gui-Song Xia, Marcello Pelillo
2020 J jnl
CoRR
Zhucun Xue, Nan Xue, Gui-Song Xia
2020 A* conf
CVPR
Nan Xue, Tianfu Wu, Song Bai, Fudong Wang, Gui-Song Xia, Liangpei Zhang, Philip H. S. Torr
2020 J jnl
CoRR
Nan Xue, Tianfu Wu, Song Bai, Fu-Dong Wang, Gui-Song Xia, Liangpei Zhang, Philip H. S. Torr
2020 J jnl
CoRR
Linxi Huan, Xianwei Zheng, Nan Xue, Wei He, Jianya Gong, Gui-Song Xia
2020 A* conf
CVPR
Fudong Wang, Nan Xue, Jin-Gang Yu, Gui-Song Xia
2020 J jnl
CoRR
Fudong Wang, Nan Xue, Jin-Gang Yu, Gui-Song Xia
2019 J jnl
CoRR
Fudong Wang, Gui-Song Xia, Nan Xue, Yipeng Zhang, Marcello Pelillo
2019 J jnl
Comput. Vis. Image Underst.
Gui-Song Xia, Jin Huang, Nan Xue, Qikai Lu, Xiaoxiang Zhu
2019 A* conf
CVPR
Nan Xue, Song Bai, Fudong Wang, Gui-Song Xia, Tianfu Wu, Liangpei Zhang
2019 J jnl
CoRR
Nan Xue, Song Bai, Fudong Wang, Gui-Song Xia, Tianfu Wu, Liangpei Zhang, Philip H. S. Torr
2019 A* conf
CVPR
Jian Ding, Nan Xue, Yang Long, Gui-Song Xia, Qikai Lu
2019 A* conf
CVPR
Zhucun Xue, Nan Xue, Gui-Song Xia, Weiming Shen
2019 J jnl
CoRR
Zhucun Xue, Nan Xue, Gui-Song Xia, Weiming Shen
2019 J jnl
Pattern Recognit. Lett.
Hui Chen, Nan Xue, Yipeng Zhang, Qikai Lu, Gui-Song Xia
2018 conf
ECCV (16)
Fudong Wang, Nan Xue, Yipeng Zhang, Xiang Bai, Gui-Song Xia
2018 J jnl
CoRR
Fudong Wang, Nan Xue, Yipeng Zhang, Xiang Bai, Gui-Song Xia
2018 J jnl
IEEE Trans. Image Process.
Nan Xue, Gui-Song Xia, Xiang Bai, Liangpei Zhang, Weiming Shen
2018 J jnl
CoRR
Gui-Song Xia, Jin Huang, Nan Xue, Qikai Lu, Xiaoxiang Zhu
2018 J jnl
CoRR
Nan Xue, Song Bai, Fudong Wang, Gui-Song Xia, Tianfu Wu, Liangpei Zhang
2018 J jnl
CoRR
Jian Ding, Nan Xue, Yang Long, Gui-Song Xia, Qikai Lu
2017 J jnl
CoRR
Nan Xue, Gui-Song Xia, Xiang Bai, Liangpei Zhang, Weiming Shen
2015 C conf
IGARSS
Bowen Xu, Nan Xue, Gui-Song Xia, Liangpei Zhang
2014 C conf
IGARSS
Nan Xue, Gui-Song Xia, Liangpei Zhang
2014 C conf
IGARSS
Gang Liu, Gui-Song Xia, Wen Yang, Nan Xue
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])