Kang Yang

183 papers A* 12A 3B 10C 2Misc 2Journal 117Unranked 37
YearRankTypeTitle / Venue / Authors
2026 J jnl
Comput. J.
Jing Li, Yucheng Han, Xudong Wang, Xinglong Zhang, Lili Zhang, Wei Wei, Pei Yu, Hongxin Tan, Kang Yang
2026 J jnl
CoRR
Kang Yang, Peng Wang, Lantao Li, Tianci Bu, Chen Sun, Deying Li, Yongcai Wang
2026 J jnl
Int. J. Pattern Recognit. Artif. Intell.
Yadong Yang, Kang Yang, Deyong She, Shijian Zheng, Changmin Zhan, Yuqing Zhang, Xiancun Zhou
2026 J jnl
Displays
Yana Gao, Cong Peng, Kang Yang, Xifeng Li, Jianhua Zhang
2026 J jnl
J. Supercomput.
Lili Zhang, Wenshuo Han, Kang Yang, Ke Zhang, Long Zhang, Ruiyang Xiao, Jing Li, Wei Wei, Pei Yu, Hongxin Tan
2026 J jnl
CoRR
Yuang Geng, Junkai Zhou, Kang Yang, Pan He, Zhuoyang Zhou, José C. Príncipe, Joel B. Harley, Ivan Ruchkin
2026 J jnl
Displays
Yana Gao, Kang Yang, Tuo Zheng, Cong Peng, Xingyao Zhou, Xiao Ling, Xifeng Li, Jianhua Zhang
2026 J jnl
CAAI Trans. Intell. Technol.
Xinghua Pan, Zexin Feng, Kang Yang
2026 J jnl
Eng. Appl. Artif. Intell.
Congcong Fan, Youliang Ding, Kang Yang
2026 A* conf
AAAI
Yifan Liang, Andong Li, Kang Yang, Guochen Yu, Fangkun Liu, Lingling Dai, Xiaodong Li, Chengshi Zheng
2026 J jnl
CoRR
Yifan Liang, Andong Li, Kang Yang, Guochen Yu, Fangkun Liu, Lingling Dai, Xiaodong Li, Chengshi Zheng
2025 J jnl
IEEE Trans. Knowl. Data Eng.
Songwei Zhao, Bo Yu, Kang Yang, Sinuo Zhang, Jifeng Hu, Yuan Jiang, Philip S. Yu, Hechang Chen
2025 conf
ASIACRYPT (4)
Tianrui Wang, Anyu Wang, Kang Yang, Hanlin Liu, Yu Yu, Jun Zhang, Xiaoyun Wang
2025 J jnl
IACR Cryptol. ePrint Arch.
Tianrui Wang, Anyu Wang, Kang Yang, Hanlin Liu, Yu Yu, Jun Zhang, Xiaoyun Wang
2025 B conf
ICPADS
Yadong Yang, Chengcheng Jia, Kang Yang, Deyong She, Xin An, Xiancun Zhou
2025 J jnl
Robotics Comput. Integr. Manuf.
Kang Yang, Yongkui Liu, Benben Tuo, Yaduo Pan, Xinyu Wang, Lin Zhang, Lihui Wang
2025 J jnl
IACR Cryptol. ePrint Arch.
Hanlin Liu, Xiao Wang, Kang Yang, Longhui Yin, Yu Yu
2025 A* conf
SP
Kang Yang, Guanhong Tao, Xun Chen, Jun Xu
2025 J jnl
CoRR
Kang Yang, Guanhong Tao, Xun Chen, Jun Xu
2025 J jnl
Eng. Appl. Artif. Intell.
Xujia Liu, Youliang Ding, Fei Xu, Yichao Xu, Kang Yang
2025 J jnl
CoRR
Ruikai Zhou, Kang Yang, Xun Chen, Wendy Hui Wang, Guanhong Tao, Jun Xu
2025 J jnl
Knowl. Inf. Syst.
Kang Yang, Ruiyun Yu
2025 J jnl
CoRR
Lantao Li, Kang Yang, Rui Song, Chen Sun
2025 J jnl
J. Supercomput.
Lili Zhang, Ke Zhang, Kang Yang, Wei Wei, Jing Li, Hongxin Tan, Pei Yu, Yucheng Han, Xudong Yang
2025 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Kang Yang, Jianwang Zhai, Liuyu Xiang, Zixi Huang, Dan Wu, Yida Wang, Kang Zhao, Ming Lei, Zhaofeng He
2025 conf
ICCBN
Cheng Qian, Li Lin, Kang Yang
2025 J jnl
IEEE Trans. Control. Syst. Technol.
Di Liu, Simone Baldi, Kang Yang, Alessandro Astolfi
2025 conf
WHICEB (1)
Jing Yang, Kang Yang, Qiuying Gu, Ningnan Zhou, Yucheng Zhang, Xiang Shu
2025 J jnl
IACR Cryptol. ePrint Arch.
Jiangxia Ge, Kang Yang, Yang Yu, Yu Yu
2025 J jnl
IEEE Trans. Affect. Comput.
Chang Cai, Jiahui Wang, Jun Lin, Kang Yang, Huicong Kang, Jingying Chen, Wei Wu
2025 J jnl
CoRR
Kang Yang, Yunhang Zhang, Zichuan Li, Guanhong Tao, Jun Xu, Xiaojing Liao
2025 J jnl
IEEE Trans. Ind. Informatics
Kang Yang, Zhenhan Lin, Zekun Yang, Zhihui Tian, Jie Ma, José C. Príncipe, Joel B. Harley
2025 J jnl
IACR Cryptol. ePrint Arch.
Yubo Zeng, Kang Yang, Dengguo Feng, Min Zhang
2025 J jnl
CoRR
Chenqi Lin, Kang Yang, Tianshi Xu, Ling Liang, Yufei Wang, Zhaohui Chen, Runsheng Wang, Mingyu Gao, Meng Li
2025 A* conf
ICRA
Kang Yang, Tianci Bu, Lantao Li, Chunxu Li, Yongcai Wang, Deying Li
2025 J jnl
CoRR
Kang Yang, Tianci Bu, Lantao Li, Chunxu Li, Yongcai Wang, Deying Li
2025 J jnl
CoRR
Kang Yang, Yifan Liang, Fangkun Liu, Zhenping Xie, Chengshi Zheng
2025 A conf
INTERSPEECH
Yifan Liang, Kang Yang, Fangkun Liu, Andong Li, Xiaodong Li, Chengshi Zheng
2025 J jnl
CoRR
Kang Yang, Jingxue Chen, Qingkun Tang, Tianxiang Zhang, Qianchun Lu
2025 B conf
IEEE Big Data
Kang Yang, Chungen Xu, Lei Xu, Pan Zhang, Rui Zhang
2025 J jnl
IEEE Internet Things J.
Kang Yang, Di Liu, Simone Baldi, Wenwu Yu, Chen Lv
2025 A* conf
ICML
Tianci Bu, Le Zhou, Wenchuan Yang, Jianhong Mou, Kang Yang, Suoyi Tan, Feng Yao, Jingyuan Wang, Xin Lu
2025 J jnl
CoRR
Tianci Bu, Le Zhou, Wenchuan Yang, Jianhong Mou, Kang Yang, Suoyi Tan, Feng Yao, Jingyuan Wang, Xin Lu
2025 conf
ICCVW
Lantao Li, Kang Yang, Wenqi Zhang, Xiaoxue Wang, Chen Sun
2025 J jnl
CoRR
Lantao Li, Kang Yang, Wenqi Zhang, Xiaoxue Wang, Chen Sun
2025 J jnl
Eng. Appl. Artif. Intell.
Lili Zhang, Kang Yang, Yucheng Han, Jing Li, Wei Wei, Hongxin Tan, Pei Yu, Ke Zhang, Xudong Yang
2025 J jnl
Expert Syst. Appl.
Jie Fu, Lina Wang, Jianpeng Ke, Kang Yang, Rongwei Yu
2025 B conf
ICPADS
Rui Zhang, Chungen Xu, Lei Xu, Pan Zhang, Kang Yang
2025 J jnl
J. Supercomput.
Kang Yang, Lili Zhang, Yucheng Han, Ke Zhang, Jing Li, Wei Wei, Hongxin Tan, Pei Yu
2025 A conf
IROS
Yuang Geng, Yang Zhou, Yuyang Zhang, Zhongzheng Ren Zhang, Kang Yang, Tyler Ruble, Giancarlo Vidal, Ivan Ruchkin
2025 conf
ICIC (19)
Kang Yang, Xingyu Lu
2024 conf
CASE
Kang Yang, Yongcai Wang, Yunjun Han, Qing-Shan Jia
2024 J jnl
Inf. Process. Manag.
Zhiwei Yang, Jing Ma, Kang Yang, Huiru Lin, Hechang Chen, Ruichao Yang, Yi Chang
2024 J jnl
J. Comput. Inf. Sci. Eng.
Hao Chen, Hongbin Lin, Qingfeng Xu, Yaguan Li, Yiming Zheng, Jianghua Fei, Kang Yang, Wenhui Fan, Zhenguo Nie
2024 A* conf
WWW
Tianci Bu, Kang Yang, Wenchuan Yang, Jiawei Feng, Xiaoyu Zhang, Xin Lu
2024 J jnl
IEEE Trans. Intell. Transp. Syst.
Kang Yang, Di Liu, Simone Baldi, Wenwu Yu, Chen Lv
2024 J jnl
IEEE Trans. Instrum. Meas.
Kang Yang, Yongle Zhang, Ahui Zhao, Hongwei Zhang, Qiannian Zhang, Daorong Rui, Xiang Wang, Dengchao Huang
2024 J jnl
Des. Codes Cryptogr.
Yuxin Tong, Xiang Xie, Kang Yang, Rui Zhang, Rui Xue
2024 J jnl
CoRR
Kang Yang, Myia Dickens, James P. Schmiedeler, Edgar A. Bolívar-Nieto
2024 J jnl
Vis. Comput.
Pengjie Wang, Kang Yang, Chengzhi Yuan, Houjie Li, Wen Tang, Xiaosong Yang
2024 J jnl
IEEE Trans. Knowl. Data Eng.
Kang Yang, Ruiyun Yu, Bingyang Guo, Jie Li
2024 J jnl
Knowl. Based Syst.
Kang Yang, Ruiyun Yu, Bingyang Guo, Shi Zhen
2024 conf
ITSC
Xinshi Zhao, Di Liu, Kang Yang, Simone Baldi
2024 J jnl
IEEE Trans. Intell. Transp. Syst.
Kang Yang, Di Liu, Simone Baldi, Chen Lv
2024 J jnl
IET Commun.
Changliang Zheng, Kang Yang, Tielian Fu, Tianle Liu, Mengqi Yang
2024 A* conf
NeurIPS
Hongyu Sun, Qiuhong Ke, Yongcai Wang, Wang Chen, Kang Yang, Deying Li, Jianfei Cai
2024 J jnl
CoRR
Hongyu Sun, Qiuhong Ke, Yongcai Wang, Wang Chen, Kang Yang, Deying Li, Jianfei Cai
2024 J jnl
IEEE Trans. Intell. Veh.
Di Liu, Sebastian Mair, Kang Yang, Simone Baldi, Paolo Frasca, Matthias Althoff
2024 A* conf
SP
Ruikai Zhou, Kang Yang, Xiuling Wang, Wendy Hui Wang, Jun Xu
2024 J jnl
IACR Cryptol. ePrint Arch.
Jiaxing He, Kang Yang, Guofeng Tang, Zhangjie Huang, Li Lin, Changzheng Wei, Ying Yan, Wei Wang
2024 J jnl
IEEE Access
Hongchang Zhang, Kang Yang, Heng Liu, Jiali Hu, Yao Shu, Juan Zeng
2024 J jnl
Knowl. Based Syst.
Kang Yang, Zhiwei Yang, Songwei Zhao, Zhejian Yang, Sinuo Zhang, Hechang Chen
2024 conf
DDDAS/Infosymbiotics
Kang Yang, Zekun Yang, Zhihui Tian, Harsha Vardhan Tetali, Joel B. Harley
2024 J jnl
CoRR
Li Zeng, Haohan Huang, Binfan Zheng, Kang Yang, Sheng Cheng Shao, Jinhua Zhou, Jun Xie, Rongqian Zhao, Xin Chen
2023 J jnl
CoRR
Chunxi Guo, Zhiliang Tian, Jintao Tang, Pancheng Wang, Zhihua Wen, Kang Yang, Ting Wang
2023 J jnl
Complex Intell. Syst.
Jinyuan Mo, Rui Wang, Mengda Cao, Kang Yang, Xu Yang, Tao Zhang
2023 J jnl
IET Image Process.
Jielin Jiang, Kang Yang, Xiaolong Xu, Yan Cui
2023 J jnl
Remote. Sens.
Xiaomi Wang, Jiuhong Liu, Peng Peng, Yiyun Chen, Shan He, Kang Yang
2023 J jnl
IEEE Geosci. Remote. Sens. Lett.
Yan-E. Hou, Kang Yang, Lanxue Dang, Yang Liu
2023 J jnl
Int. J. Model. Simul. Sci. Comput.
Guofang Li, Kang Yang, Zhiyu Dong, Xiaoli Ji, Shaopei Wu
2023 J jnl
World Wide Web (WWW)
Jie Fu, Lina Wang, Jianpeng Ke, Kang Yang, Rongwei Yu
2023 J jnl
Swarm Evol. Comput.
Xu Yang, Wenhua Li, Rui Wang, Kang Yang
2023 J jnl
J. Comput. Inf. Sci. Eng.
Hao Chen, Zhenguo Nie, Qingfeng Xu, Jianghua Fei, Kang Yang, Yaguan Li, Hongbin Lin, Wenhui Fan, Xin-Jun Liu
2023 J jnl
AI Commun.
Ruiyun Yu, Kang Yang, Zhihong Wang, Shi Zhen
2023 J jnl
CoRR
Kang Yang, Kunhao Lai
2023 conf
PRICAI (2)
Chunxi Guo, Zhiliang Tian, Jintao Tang, Pancheng Wang, Zhihua Wen, Kang Yang, Ting Wang
2023 J jnl
IEEE Trans. Multim.
Binglu Wang, Kang Yang, Yongqiang Zhao, Teng Long, Xuelong Li
2023 J jnl
CoRR
Di Liu, Sebastian Mair, Kang Yang, Simone Baldi, Paolo Frasca, Matthias Althoff
2023 conf
IRPS
Kang Yang, Suhui Yang, Yan Ouyang, Shengwei Yang, Kun Han, Yi He
2023 conf
PACIS
Xiaoyu Zhang, Kang Yang, Xuanhui Zhang, Xinyue Li, Qinghua Zhu
2022 J jnl
Comput. Aided Des.
Kang Yang, Ye Tian, Tielin Shi, Qi Xia
2022 A* conf
IJCAI
Xiang Huang, Hongsheng Liu, Beiji Shi, Zidong Wang, Kang Yang, Yang Li, Min Wang, Haotian Chu, Jing Zhou, Fan Yu, Bei Hua, Bin Dong, Lei Chen
2022 J jnl
J. Comput. Des. Eng.
Ruizhao Zheng, Yong Zhang, Kang Yang
2022 J jnl
CoRR
Guhong Nie, Lirui Xiao, Menglong Zhu, Dongliang Chu, Yue Shen, Peng Li, Kang Yang, Li Du, Bo Chen
2022 J jnl
IEEE Trans. Instrum. Meas.
Kang Yang, Dan Wu, Wengen Gao, Tianming Ni, Qiannian Zhang, Hongwei Zhang, Dengchao Huang
2022 J jnl
IEEE Access
Dengdi Sun, Kang Yang, Zhuanlian Ding
2022 conf
AIM
Kang Yang, Revanth Damerla, Shorya Awtar
2022 Misc conf
Inscrypt
Qi Wang, Wenxin Li, Kang Yang, Yiru Zhao, Lei Zhao, Lina Wang
2022 conf
HPEC
Li Zeng, Kang Yang, Haoran Cai, Jinhua Zhou, Rongqian Zhao, Xin Chen
2022 B conf
IJCNN
Zhengwu Luo, Lina Wang, Run Wang, Kang Yang, Aoshuang Ye
2022 A* conf
NeurIPS
Xiang Huang, Zhanhong Ye, Hongsheng Liu, Beiji Shi, Zidong Wang, Kang Yang, Yang Li, Min Wang, Haotian Chu, Fan Yu, Bei Hua, Lei Chen, Bin Dong
2022 A* conf
IJCAI
Kang Yang, Run Wang, Lina Wang
2022 B conf
IJCNN
Jianrong Xu, Boyu Diao, Bifeng Cui, Kang Yang, Chao Li, Hailong Hong
2022 J jnl
Remote. Sens.
Hailing Xie, Zhien Wang, Tao Luo, Kang Yang, Damao Zhang, Tian Zhou, Xueling Yang, Xiaohong Liu, Qiang Fu
2022 J jnl
IEEE Trans. Instrum. Meas.
Ruiyun Yu, Bingyang Guo, Kang Yang
2022 J jnl
CoRR
Guoyu Li, Kang Yang
2022 A conf
CIKM
Ruiyun Yu, Kang Yang, Bingyang Guo
2021 J jnl
Neurocomputing
Jielin Jiang, Kang Yang, Jian Yang, Zhi-Xin Yang, Yadang Chen, Lei Luo
2021 conf
TALE
Kang Yang, Jingying Chen, Chang Cai
2021 B conf
IJCNN
Yangchun Yan, Rongzuo Guo, Chao Li, Kang Yang, Yongjun Xu
2021 J jnl
J. Vis.
Kang Yang, Xin Cao, Guohua Geng, Kang Li, Mingquan Zhou
2021 B conf
ICPADS
Kang Yang, Rongyu Cao, Yueyuan Zhou, Jiawei Zhang, En Shao, Guangming Tan
2021 conf
ICMLSC
Liang Du, Kang Yang, Yunhui Liang, Xiaolin Lv
2021 J jnl
Remote. Sens.
Hao Sun, Jing Yang, Qilin Zhang, Lin Song, Haiyang Gao, Xiaoqin Jing, Guo Lin, Kang Yang
2021 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Jiaqing Fan, Huihui Song, Kaihua Zhang, Kang Yang, Qingshan Liu
2021 J jnl
CoRR
Xiang Huang, Zhanhong Ye, Hongsheng Liu, Beiji Shi, Zidong Wang, Kang Yang, Yang Li, Bingya Weng, Min Wang, Haotian Chu, Jing Zhou, Fan Yu, Bei Hua, Lei Chen, Bin Dong
2021 J jnl
Comput. Ind. Eng.
Kang Yang, Rui Wang, Huihui He, Xu Yang, Guo Zhang
2021 conf
EMBC
Hongyang Jiang, Mengdi Gao, Kang Yang, Dongdong Zhang, He Ma, Wei Qian
2021 conf
CACRE
Kang Yang, Songyi Dian, Bin Guo
2021 J jnl
CoRR
Qigong Sun, Xiufang Li, Fanhua Shang, Hongying Liu, Kang Yang, Licheng Jiao, Zhouchen Lin
2021 J jnl
CoRR
Xiang Huang, Hongsheng Liu, Beiji Shi, Zidong Wang, Kang Yang, Yang Li, Bingya Weng, Min Wang, Haotian Chu, Jing Zhou, Fan Yu, Bei Hua, Lei Chen, Bin Dong
2021 J jnl
J. Inf. Process. Syst.
Guoyu Li, Kang Yang
2020 J jnl
IEEE Robotics Autom. Lett.
Zemin Liu, Bohan Chen, Shuzhang Liang, Yingchun Guan, Li Wen, Jiaqi Liu, He Wang, Xiao Yu, Kang Yang, Wenbo Liu, Shilin Nie, Wenguang Sun, Zhexin Xie
2020 conf
EMBC
Hongyang Jiang, Jie Xu, Rongjie Shi, Kang Yang, Dongdong Zhang, Mengdi Gao, He Ma, Wei Qian
2020 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Aibin Yan, Zhelong Xu, Kang Yang, Jie Cui, Zhengfeng Huang, Patrick Girard, Xiaoqing Wen
2020 J jnl
Appl. Intell.
Kang Yang, Xiaoming You, Sheng Liu, Han Pan
2020 J jnl
Int. J. Netw. Secur.
Kang Yang, Guohua Wu, Chengcheng Dong, Xingbing Fu, Fagen Li, Ting Wu
2020 J jnl
CoRR
Yangchun Yan, Chao Li, Rongzuo Guo, Kang Yang, Yongjun Xu
2020 J jnl
Symmetry
Yuting Wang, Chunhua Li, Kang Yang
2020 J jnl
Bioinform.
Lingwei Xie, Song He, Zhongnan Zhang, Kunhui Lin, Xiaochen Bo, Shu Yang, Boyuan Feng, Kun Wan, Kang Yang, Jie Yang, Yufei Ding
2020 J jnl
Neural Comput. Appl.
Kang Yang, Huihui Song, Kaihua Zhang, Qingshan Liu
2020 A* conf
ACM Multimedia
Lina Wang, Kang Yang, Wenqi Wang, Run Wang, Aoshuang Ye
2020 J jnl
CoRR
Jianrong Xu, Chao Li, Bifeng Cui, Kang Yang, Yongjun Xu
2020 conf
ECCV Workshops (5)
Matej Kristan, Ales Leonardis, Jiri Matas, Michael Felsberg, Roman P. Pflugfelder, Joni-Kristian Kämäräinen, Martin Danelljan, Luka Cehovin Zajc, Alan Lukezic, Ondrej Drbohlav, Linbo He, Yushan Zhang, Song Yan, Jinyu Yang, Gustavo Fernández, Alexander G. Hauptmann, Alireza Memarmoghadam, Álvaro García-Martín, Andreas Robinson, Anton Varfolomieiev, Awet Haileslassie Gebrehiwot, Bedirhan Uzun, Bin Yan, Bing Li, Chen Qian, Chi-Yi Tsai, Christian Micheloni, Dong Wang, Fei Wang, Fei Xie, Felix Järemo Lawin, Fredrik Gustafsson, Gian Luca Foresti, Goutam Bhat, Guangqi Chen, Haibin Ling, Haitao Zhang, Hakan Cevikalp, Haojie Zhao, Haoran Bai, Hari Chandana Kuchibhotla, Hasan Saribas, Heng Fan, Hossein Ghanei-Yakhdan, Houqiang Li, Houwen Peng, Huchuan Lu, Hui Li, Javad Khaghani, Jesús Bescós, Jianhua Li, Jianlong Fu, Jiaqian Yu, Jingtao Xu, Josef Kittler, Jun Yin, Junhyun Lee, Kaicheng Yu, Kaiwen Liu, Kang Yang, Kenan Dai, Li Cheng, Li Zhang, Lijun Wang, Linyuan Wang, Luc Van Gool, Luca Bertinetto, Matteo Dunnhofer, Miao Cheng, Mohana Murali Dasari, Ning Wang, Pengyu Zhang, Philip H. S. Torr, Qiang Wang, Radu Timofte, Rama Krishna Sai Subrahmanyam Gorthi, Seokeon Choi, Seyed Mojtaba Marvasti-Zadeh, Shao-Chuan Zhao, Shohreh Kasaei, Shoumeng Qiu, Shuhao Chen, Thomas B. Schön, Tianyang Xu, Wei Lu, Weiming Hu, Wengang Zhou, Xi Qiu, Xiao Ke, Xiao-Jun Wu, Xiaolin Zhang, Xiaoyun Yang, Xuefeng Zhu, Yingjie Jiang, Yingming Wang, Yiwei Chen, Yu Ye, Yuezhou Li, Yuncon Yao, Yunsung Lee, Yuzhang Gu, Zezhou Wang, Zhangyong Tang, Zhenhua Feng, Zhijun Mai, Zhipeng Zhang, Zhirong Wu, Ziang Ma
2020 conf
CDC
Simone Baldi, Spandan Roy, Kang Yang
2019 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Aibin Yan, Kang Yang, Zhengfeng Huang, Jiliang Zhang, Jie Cui, Xiangsheng Fang, Maoxiang Yi, Xiaoqing Wen
2019 conf
ICII
Rui Wang, Houbing Song, Yu Jing, Kang Yang, Yong Guan, Jiaguang Sun
2019 conf
OFC
Kang Yang, Yan-Ge Liu, Zhi Wang, Hong-wei Zhang, Ya Han, Baiwei Mao, Rui-jing He
2019 J jnl
IEEE Access
Shuang Wang, Kang Yang, Kang Chen
2019 conf
EMBC
Hongyang Jiang, Kang Yang, Mengdi Gao, Dongdong Zhang, He Ma, Wei Qian
2019 conf
ICPCSEE (1)
Kang Yang, Jinghua Zhu
2019 J jnl
CoRR
Peng Bao, Wenjun Xia, Kang Yang, Weiyan Chen, Mianyi Chen, Yan Xi, Shanzhou Niu, Jiliu Zhou, He Zhang, Huaiqiang Sun, Zhangyang Wang, Yi Zhang
2019 J jnl
IEEE Trans. Medical Imaging
Peng Bao, Huaiqiang Sun, Zhangyang Wang, Yi Zhang, Wenjun Xia, Kang Yang, Weiyan Chen, Mianyi Chen, Yan Xi, Shanzhou Niu, Jiliu Zhou, He Zhang
2019 J jnl
Sensors
Biao Xiao, Bin Yang, Fu-Zhen Xuan, Yun Wan, Chaojie Hu, Pengcheng Jin, Hongshuai Lei, Yanxun Xiang, Kang Yang
2019 J jnl
IEEE Access
Dehui Zhang, Xiaoming You, Sheng Liu, Kang Yang
2019 J jnl
CoRR
Qigong Sun, Fanhua Shang, Kang Yang, Xiufang Li, Yan Ren, Licheng Jiao
2019 A* conf
AAAI
Qigong Sun, Fanhua Shang, Kang Yang, Xiufang Li, Yan Ren, Licheng Jiao
2019 J jnl
IEEE Access
Kang Yang, Jinghua Zhu
2019 conf
ISBI
Kang Yang, Wenjun Xia, Peng Bao, Jiliu Zhou, Yi Zhang
2019 J jnl
Trans. Emerg. Telecommun. Technol.
Chengcheng Dong, Kang Yang, Jian Qiu, Yuanfang Chen
2019 conf
CSAE
Kang Yang, ChangHua Liu, Xiaoming Wu, Hao Li
2019 conf
ISBI
Peng Bao, Wenjun Xia, Kang Yang, Jiliu Zhou, Yi Zhang
2019 conf
ICCV Workshops
Dawei Du, Yue Zhang, Liefeng Bo, Hailin Shi, Rui Zhu, Bo Han, Chunhui Zhang, Guizhong Liu, Han Wu, Hao Wen, Haoran Wang, Pengfei Zhu, Jiaqing Fan, Jie Chen, Jie Gao, Jie Zhang, Jinghao Zhou, Jinliu Zhou, Jinwang Wang, Jiuqing Wan, Josef Kittler, Kaihua Zhang, Longyin Wen, Kaiqi Huang, Kang Yang, Kangkai Zhang, Lianghua Huang, Lijun Zhou, Lingling Shi, Lu Ding, Ning Wang, Peng Wang, Qintao Hu, Xiao Bian, Robert Laganière, Ruiyan Ma, Ruohan Zhang, Shanrong Zou, Shengwei Zhao, Shengyang Li, Shengyin Zhu, Shikun Li, Shiming Ge, Shiyu Xuan, Haibin Ling, Tianyang Xu, Ting He, Wei Shi, Wei Song, Weiming Hu, Wenhua Zhang, Wenjun Zhu, Xi Yu, Xianhai Wang, Xiaojun Wu, Qinghua Hu, Xiaotong Li, Xiaoxue Li, Xiaoyue Yin, Xin Zhang, Xin Zhao, Xizhe Xue, Xu Lei, Xueyuan Yang, Yanjie Gao, Yanyun Zhao, Jiayu Zheng, Yinda Xu, Ying Li, Yong Wang, Yong Yang, Yuting Yang, Yuxuan Li, Zeyu Wang, Zhenhua Feng, Zhipeng Zhang, Zhiyong Yu, Tao Peng, Zhizhao Duan, Zhuojin Sun, Xinyao Wang
2019 conf
ROBIO
Yu Song, Kang Yang, Xin Jiang, Yunhui Liu
2019 J jnl
IEEE/ACM Trans. Netw.
Kang Yang, Tianzhang Xing, Yang Liu, Zhenjiang Li, Xiaoqing Gong, Xiaojiang Chen, Dingyi Fang
2018 conf
ATS
Aibin Yan, Yafei Ling, Kang Yang, Zhili Chen, Maoxiang Yi
2018 conf
SmartWorld/SCALCOM/UIC/ATC/CBDCom/IOP/SCI
Shiwei Song, Yan Lei, Kang Yang, Tianzhang Xing, Jinping Niu, Feng Chen, Dingyi Fang
2018 Misc conf
CODES+ISSS
Kang Yang, Rui Wang, Yu Jiang, Chenxia Luo, Yong Guan, Xiaojuan Li, Zhiping Shi
2018 J jnl
IEEE Access
Yi Zhang, Kang Yang, Yining Zhu, Wenjun Xia, Peng Bao, Jiliu Zhou
2018 J jnl
Appl. Math. Comput.
Ran Gu, Xueliang Li, Zhongmei Qin, Yongtang Shi, Kang Yang
2018 conf
BIBM
Kang Yang, Zhongnan Zhang, Song He, Xiaochen Bo
2018 conf
COMPSAC (1)
Chenxia Luo, Rui Wang, Yu Jiang, Kang Yang, Yong Guan, Xiaojuan Li, Zhiping Shi
2018 J jnl
Future Gener. Comput. Syst.
Kang Yang, Rui Wang, Yu Jiang, Houbing Song, Chenxia Luo, Yong Guan, Xiaojuan Li, Zhiping Shi
2018 J jnl
CoRR
Peng Bao, Wenjun Xia, Kang Yang, Jiliu Zhou, Yi Zhang
2018 B conf
SECON
Kang Yang, Xiaoqing Gong, Yang Liu, Zhenjiang Li, Tianzhang Xing, Xiaojiang Chen, Dingyi Fang
2017 J jnl
Multim. Tools Appl.
Xiu-Li Chai, Kang Yang, Zhihua Gan
2017 J jnl
Signal Process. Image Commun.
Xiu-Li Chai, Zhihua Gan, Kang Yang, Yiran Chen, Xianxing Liu
2017 conf
BigCom
Jun Tan, Kang Yang, Shiwei Song, Tianzhang Xing, Dingyi Fang
2017 J jnl
Ars Comb.
Zhongmei Qin, Jianfeng Wang, Kang Yang
2017 B conf
EWSN
Jun Tan, Kang Yang, Ruilin Li, Tianzhang Xing, Dingyi Fang
2017 B conf
ICPADS
Kang Yang, Xiaoqing Gong, Shiwei Song, Tianzhang Xing, Xiaojiang Chen, Dingyi Fang
2017 J jnl
计算机科学
Kang Yang, Haidong Yuan, Yuanbo Guo
2015 J jnl
Discuss. Math. Graph Theory
Xueliang Li, Ingo Schiermeyer, Kang Yang, Yan Zhao
2015 J jnl
Discuss. Math. Graph Theory
Xueliang Li, Ingo Schiermeyer, Kang Yang, Yan Zhao
2015 conf
CVPR Workshops
Guyue Zhou, Lu Fang, Ketan Tang, Honghui Zhang, Kai Wang, Kang Yang
2015 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Zigen Song, Kang Yang, Jian Xu, Yunchao Wei
2015 J jnl
Discuss. Math. Graph Theory
Lily Chen, Xueliang Li, Kang Yang, Yan Zhao
2014 conf
CVPR Workshops
Guyue Zhou, Ang Liu, Kang Yang, Tao Wang, Zexiang Li
2014 conf
ICIRA (2)
Jinqing Zhan, Kang Yang, Zhichao Huang
2012 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Qun Jane Gu, Kang Yang, Yi Xue, Zhiwei Xu, Adrian Tang, Chin-Chung Nien, T. H. Wu, Jenn-Hwan Tarng, Mau-Chung Frank Chang
2011 C conf
VLSI-SoC
Shaowei Zhen, Bo Zhang, Ping Luo, Kang Yang, Xiaohui Zhu, Jiangkun Li
2011 J jnl
Photonic Netw. Commun.
Kang Yang, Minming Zhang, Deming Liu, Yinbo Qian, Lei Deng
2011 C conf
VLSI-SoC
Xiaohui Zhu, Ping Luo, Shaowei Zhen, Kang Yang, Jiangkun Li, Zekun Zhou
tests/unit/test_decompile_modules.py
← Index tests/unit/test_decompile_modules.py python
"""
Unit tests for --decompile-modules flag.

Tests that:
1. CLI argument parsing and validation works correctly
2. decompile_modules is threaded through the entire call chain
3. BinaryNinjaDecompiler.analyze_binary() gates extractions per selected modules
4. DecompileBinja.prepare_export_data() filters DB tables per selected modules
"""
import os
import pytest
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.unit]


# ============================================================================
# CLI Argument Parsing Tests
# ============================================================================

class TestDecompileModulesCliArgument:
    """Tests for --decompile-modules CLI argument parsing in start.py."""

    def _parse_args(self, args_list):
        """Helper to parse CLI args without running main()."""
        import argparse

        parser = argparse.ArgumentParser()
        input_group = parser.add_mutually_exclusive_group(required=True)
        input_group.add_argument("--path")
        input_group.add_argument("--s3", action="store_true")
        input_group.add_argument("--s3-solo", metavar="S3_KEY")
        input_group.add_argument("--nomad-job", action="store_true")
        input_group.add_argument("--date", metavar="YYYY-MM-DD")
        input_group.add_argument("--range", nargs=2)
        input_group.add_argument("--analyzed", action="store_true")

        parser.add_argument("--repo")
        parser.add_argument("--index_prefix", default="redb")
        parser.add_argument("-d", "--decompile", action="store_true")
        parser.add_argument("-m", "--modules", default="all")
        parser.add_argument("--decompile-modules", default="all")
        parser.add_argument("--force", action="store_true")
        parser.add_argument("--dry-run", action="store_true")

        return parser.parse_args(args_list)

    def test_decompile_modules_default_all(self):
        """--decompile-modules defaults to 'all'."""
        args = self._parse_args(["--path", "/tmp/test", "--repo", "test"])
        assert args.decompile_modules == "all"

    def test_decompile_modules_single(self):
        """--decompile-modules accepts a single module."""
        args = self._parse_args([
            "--path", "/tmp/test", "--repo", "test",
            "-d", "--decompile-modules", "strings"
        ])
        assert args.decompile_modules == "strings"

    def test_decompile_modules_comma_separated(self):
        """--decompile-modules accepts comma-separated modules."""
        args = self._parse_args([
            "--path", "/tmp/test", "--repo", "test",
            "-d", "--decompile-modules", "cfg,llil,strings"
        ])
        assert args.decompile_modules == "cfg,llil,strings"

    def test_decompile_modules_with_decompile_flag(self):
        """--decompile-modules works with -d flag."""
        args = self._parse_args([
            "--path", "/tmp/test", "--repo", "test",
            "-d", "--decompile-modules", "disassembly"
        ])
        assert args.decompile is True
        assert args.decompile_modules == "disassembly"


# ============================================================================
# Validation Tests
# ============================================================================

class TestDecompileModulesValidation:
    """Tests for --decompile-modules validation logic in start.py."""

    def test_valid_modules_set_parsing(self):
        """Valid comma-separated modules are parsed into a set."""
        VALID = {"all", "decompilation", "disassembly", "cfg", "llil", "strings"}
        raw = "cfg,llil,strings"
        modules_set = {m.strip() for m in raw.split(",")}
        invalid = modules_set - VALID
        assert invalid == set()
        assert modules_set == {"cfg", "llil", "strings"}

    def test_invalid_module_detected(self):
        """Invalid module names are detected."""
        VALID = {"all", "decompilation", "disassembly", "cfg", "llil", "strings"}
        raw = "cfg,invalid_module"
        modules_set = {m.strip() for m in raw.split(",")}
        invalid = modules_set - VALID
        assert invalid == {"invalid_module"}

    def test_all_keyword_as_set(self):
        """'all' is parsed into {'all'} set."""
        raw = "all"
        if raw == "all":
            modules_set = {"all"}
        assert modules_set == {"all"}

    def test_whitespace_handling(self):
        """Whitespace around module names is stripped."""
        raw = " cfg , llil , strings "
        modules_set = {m.strip() for m in raw.split(",")}
        assert modules_set == {"cfg", "llil", "strings"}


# ============================================================================
# Ingestor Parameter Storage Tests
# ============================================================================

class TestIngestorDecompileModules:
    """Tests that Ingestor stores decompile_modules correctly."""

    @patch('builtins.open', MagicMock())
    @patch('redb.ingestor.multiprocessing')
    @patch('redb.ingestor.datetime')
    def test_ingestor_stores_decompile_modules(self, mock_datetime, mock_mp):
        """Ingestor stores the decompile_modules set."""
        mock_mp.Manager.return_value.dict = Mock(side_effect=[{}, {}])
        mock_datetime.today.return_value.strftime.return_value = "20260222"

        from redb.ingestor import Ingestor
        ingestor = Ingestor(
            path="/tmp/test", repository="test", index_prefix="redb",
            decompile_modules={"cfg", "strings"}
        )
        assert ingestor.decompile_modules == {"cfg", "strings"}

    @patch('builtins.open', MagicMock())
    @patch('redb.ingestor.multiprocessing')
    @patch('redb.ingestor.datetime')
    def test_ingestor_defaults_to_all(self, mock_datetime, mock_mp):
        """Ingestor defaults decompile_modules to {'all'} when not provided."""
        mock_mp.Manager.return_value.dict = Mock(side_effect=[{}, {}])
        mock_datetime.today.return_value.strftime.return_value = "20260222"

        from redb.ingestor import Ingestor
        ingestor = Ingestor(
            path="/tmp/test", repository="test", index_prefix="redb"
        )
        assert ingestor.decompile_modules == {"all"}

    @patch('builtins.open', MagicMock())
    @patch('redb.ingestor.multiprocessing')
    @patch('redb.ingestor.datetime')
    def test_ingestor_none_defaults_to_all(self, mock_datetime, mock_mp):
        """Ingestor converts None decompile_modules to {'all'}."""
        mock_mp.Manager.return_value.dict = Mock(side_effect=[{}, {}])
        mock_datetime.today.return_value.strftime.return_value = "20260222"

        from redb.ingestor import Ingestor
        ingestor = Ingestor(
            path="/tmp/test", repository="test", index_prefix="redb",
            decompile_modules=None
        )
        assert ingestor.decompile_modules == {"all"}


# ============================================================================
# Function Chain Threading Tests
# ============================================================================

class TestDecompileModulesThreading:
    """Tests that decompile_modules is correctly threaded through the call chain."""

    @patch('redb.workers.process_binary_file')
    @patch('redb.workers.is_binary_file', return_value=True)
    def test_process_file_internal_passes_decompile_modules(self, mock_is_binary, mock_process):
        """_process_file_internal passes decompile_modules to process_binary_file."""
        from redb.ingestor import _process_file_internal

        mock_process.return_value = (Mock(), "pebin")
        logger = Mock()
        modules = {"cfg", "strings"}

        _process_file_internal(
            "/tmp/test.bin", False, "redb", logger,
            decompile_modules=modules
        )

        mock_process.assert_called_once()
        call_kwargs = mock_process.call_args[1]
        assert call_kwargs["decompile_modules"] == modules

    @patch('redb.workers.process_binary_file')
    @patch('redb.workers.is_binary_file', return_value=True)
    def test_process_file_internal_default_decompile_modules_none(self, mock_is_binary, mock_process):
        """_process_file_internal defaults decompile_modules to None."""
        from redb.ingestor import _process_file_internal

        mock_process.return_value = (Mock(), "pebin")
        logger = Mock()

        _process_file_internal("/tmp/test.bin", False, "redb", logger)

        call_kwargs = mock_process.call_args[1]
        assert call_kwargs["decompile_modules"] is None

    @patch('redb.workers._process_file_internal')
    def test_process_file_passes_decompile_modules(self, mock_internal):
        """process_file passes decompile_modules to _process_file_internal."""
        from redb.workers import process_file

        mock_internal.return_value = (Mock(), "pebin")
        modules = {"llil", "disassembly"}

        with patch('redb.workers.setup_direct_logger', return_value=Mock()):
            process_file(
                "/tmp/test.bin", False, "redb", "/tmp/log", 1, 1,
                decompile_modules=modules
            )

        mock_internal.assert_called_once()
        call_kwargs = mock_internal.call_args[1]
        assert call_kwargs["decompile_modules"] == modules

    @patch('redb.workers._process_file_internal')
    def test_process_s3_file_passes_decompile_modules(self, mock_internal):
        """process_s3_file passes decompile_modules to _process_file_internal."""
        from redb.workers import process_s3_file

        mock_internal.return_value = (Mock(), "pebin")
        modules = {"cfg"}

        with patch('redb.workers.setup_direct_logger', return_value=Mock()), \
             patch('redb.workers.download_s3_object', return_value="/tmp/downloaded.bin"):
            process_s3_file(
                "bucket", "key", "/tmp", False, "redb", "/tmp/log", 1, 1,
                decompile_modules=modules
            )

        mock_internal.assert_called_once()
        call_kwargs = mock_internal.call_args[1]
        assert call_kwargs["decompile_modules"] == modules

    @patch('redb.workers.process_binary_file')
    def test_process_zip_passes_decompile_modules(self, mock_process):
        """process_zip_file passes decompile_modules to process_binary_file."""
        from redb.workers import process_zip_file

        mock_process.return_value = (Mock(), "pebin")
        logger = Mock()
        modules = {"strings", "decompilation"}

        import tempfile
        import zipfile

        with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as tmp:
            tmp_path = tmp.name

        try:
            with zipfile.ZipFile(tmp_path, 'w') as zf:
                zf.writestr("test.bin", b"\x00" * 100)

            process_zip_file(
                tmp_path, False, "redb", logger, "all",
                decompile_modules=modules
            )

            mock_process.assert_called_once()
            call_kwargs = mock_process.call_args[1]
            assert call_kwargs["decompile_modules"] == modules
        finally:
            os.unlink(tmp_path)

    @patch('redb.workers.process_binary_file')
    def test_process_7zip_passes_decompile_modules(self, mock_process):
        """process_7zip_file passes decompile_modules to process_binary_file."""
        from redb.workers import process_7zip_file

        mock_process.return_value = (Mock(), "pebin")
        logger = Mock()
        modules = {"cfg", "llil"}

        with patch('redb.workers.py7zr') as mock_py7zr:
            mock_zf = Mock()
            mock_py7zr.SevenZipFile.return_value.__enter__ = Mock(return_value=mock_zf)
            mock_py7zr.SevenZipFile.return_value.__exit__ = Mock(return_value=False)

            def fake_extractall(path):
                dest = os.path.join(path, "test.bin")
                with open(dest, "wb") as f:
                    f.write(b"\x00" * 100)

            mock_zf.extractall = fake_extractall

            process_7zip_file(
                "/tmp/test.7z", False, "redb", logger, "all",
                decompile_modules=modules
            )

            if mock_process.called:
                call_kwargs = mock_process.call_args[1]
                assert call_kwargs["decompile_modules"] == modules

    def test_worker_unpacks_decompile_modules(self):
        """worker() correctly unpacks decompile_modules from args tuple."""
        from redb.workers import worker

        modules = {"strings", "cfg"}

        with patch('redb.workers.process_file') as mock_pf, \
             patch('redb.workers.signal'), \
             patch('redb.workers.gc'):
            mock_pf.return_value = (Mock(), "pebin")

            args = (
                "/tmp/test.bin",  # filepath
                True,             # decompile
                "redb",           # index_prefix
                "/tmp/log",       # log_file
                1,                # file_number
                10,               # total_files
                "all",            # selected_modules
                False,            # dry_run
                False,            # yara_scan
                False,            # with_yara
                False,            # force
                modules,          # decompile_modules
            )

            worker(args)

            mock_pf.assert_called_once()
            call_kwargs = mock_pf.call_args[1]
            assert call_kwargs["decompile_modules"] == modules


# ============================================================================
# BinaryNinjaDecompiler._module_selected() Tests
# ============================================================================

class TestModuleSelected:
    """Tests for BinaryNinjaDecompiler._module_selected() helper."""

    def _make_decompiler(self, decompile_modules):
        """Create a minimal BinaryNinjaDecompiler-like object for testing _module_selected."""

        class FakeDecompiler:
            def __init__(self, modules):
                self.decompile_modules = modules

            def _module_selected(self, module_name):
                return "all" in self.decompile_modules or module_name in self.decompile_modules

        return FakeDecompiler(decompile_modules)

    def test_all_selects_everything(self):
        d = self._make_decompiler({"all"})
        assert d._module_selected("strings") is True
        assert d._module_selected("decompilation") is True
        assert d._module_selected("disassembly") is True
        assert d._module_selected("cfg") is True
        assert d._module_selected("llil") is True

    def test_specific_module_selected(self):
        d = self._make_decompiler({"cfg", "strings"})
        assert d._module_selected("cfg") is True
        assert d._module_selected("strings") is True
        assert d._module_selected("decompilation") is False
        assert d._module_selected("disassembly") is False
        assert d._module_selected("llil") is False

    def test_empty_set_selects_nothing(self):
        d = self._make_decompiler(set())
        assert d._module_selected("strings") is False
        assert d._module_selected("decompilation") is False

    def test_single_module(self):
        d = self._make_decompiler({"llil"})
        assert d._module_selected("llil") is True
        assert d._module_selected("cfg") is False
        assert d._module_selected("strings") is False


# ============================================================================
# analyze_binary() Selective Execution Tests
# ============================================================================

class TestAnalyzeBinaryGating:
    """Tests that analyze_binary() gates extraction per decompile_modules.

    Uses a FakeDecompiler to test the gating logic without importing binaryninja.
    """

    def _make_analyze_binary_runner(self, decompile_modules):
        """Create a test harness that simulates the gating logic of analyze_binary()."""
        run_all = "all" in decompile_modules
        run_strings = run_all or "strings" in decompile_modules
        run_decompilation = run_all or "decompilation" in decompile_modules
        run_disassembly = run_all or "disassembly" in decompile_modules
        run_llil = run_all or "llil" in decompile_modules
        run_cfg = run_all or "cfg" in decompile_modules
        need_per_function = run_decompilation or run_disassembly or run_llil or run_cfg

        return {
            "run_strings": run_strings,
            "run_decompilation": run_decompilation,
            "run_disassembly": run_disassembly,
            "run_llil": run_llil,
            "run_cfg": run_cfg,
            "need_per_function": need_per_function,
        }

    def test_all_runs_everything(self):
        r = self._make_analyze_binary_runner({"all"})
        assert r["run_strings"] is True
        assert r["run_decompilation"] is True
        assert r["run_disassembly"] is True
        assert r["run_llil"] is True
        assert r["run_cfg"] is True
        assert r["need_per_function"] is True

    def test_strings_only_skips_per_function_loop(self):
        """Selecting only 'strings' should skip the per-function loop entirely."""
        r = self._make_analyze_binary_runner({"strings"})
        assert r["run_strings"] is True
        assert r["run_decompilation"] is False
        assert r["run_disassembly"] is False
        assert r["run_llil"] is False
        assert r["run_cfg"] is False
        assert r["need_per_function"] is False

    def test_cfg_only_runs_cfg_and_disassembly_in_loop(self):
        """Selecting only 'cfg' should run the per-function loop but skip decompilation/llil/strings."""
        r = self._make_analyze_binary_runner({"cfg"})
        assert r["run_strings"] is False
        assert r["run_decompilation"] is False
        assert r["run_disassembly"] is False  # Not selected (but backbone runs anyway in real code)
        assert r["run_llil"] is False
        assert r["run_cfg"] is True
        assert r["need_per_function"] is True

    def test_decompilation_only(self):
        r = self._make_analyze_binary_runner({"decompilation"})
        assert r["run_decompilation"] is True
        assert r["run_strings"] is False
        assert r["run_cfg"] is False
        assert r["run_llil"] is False
        assert r["need_per_function"] is True

    def test_multiple_modules(self):
        r = self._make_analyze_binary_runner({"cfg", "llil", "strings"})
        assert r["run_strings"] is True
        assert r["run_cfg"] is True
        assert r["run_llil"] is True
        assert r["run_decompilation"] is False
        assert r["run_disassembly"] is False
        assert r["need_per_function"] is True

    def test_disassembly_only(self):
        r = self._make_analyze_binary_runner({"disassembly"})
        assert r["run_disassembly"] is True
        assert r["run_decompilation"] is False
        assert r["run_strings"] is False
        assert r["run_cfg"] is False
        assert r["run_llil"] is False
        assert r["need_per_function"] is True


# ============================================================================
# prepare_export_data() Table Filtering Tests
# ============================================================================

class TestPrepareExportDataFiltering:
    """Tests that prepare_export_data() only includes tables for selected modules.

    Simulates the filtering logic from DecompileBinja.prepare_export_data()
    without importing binaryninja.
    """

    def _get_export_tables(self, decompile_modules):
        """Simulate the table selection logic from prepare_export_data()."""
        run_all = "all" in decompile_modules
        run_decompilation = run_all or "decompilation" in decompile_modules
        run_disassembly = run_all or "disassembly" in decompile_modules
        run_llil = run_all or "llil" in decompile_modules
        run_cfg = run_all or "cfg" in decompile_modules
        run_strings = run_all or "strings" in decompile_modules

        tables = set()
        if run_decompilation:
            tables.update(["decompiled_content", "decompiled_refs"])
        if run_disassembly:
            tables.update(["disassembled_content", "disassembled_refs", "function_similarity_metrics"])
        if run_llil:
            tables.update(["llil_content", "llil_refs"])
        if run_cfg:
            tables.update(["cfg_functions"])
        if run_strings:
            tables.update(["strings_raw"])
        # Errors always included if per-function loop ran
        if run_decompilation or run_disassembly or run_llil or run_cfg:
            tables.add("function_analysis_errors")

        return tables

    def test_all_includes_all_tables(self):
        tables = self._get_export_tables({"all"})
        assert "decompiled_content" in tables
        assert "decompiled_refs" in tables
        assert "disassembled_content" in tables
        assert "disassembled_refs" in tables
        assert "function_similarity_metrics" in tables
        assert "llil_content" in tables
        assert "llil_refs" in tables
        assert "cfg_functions" in tables
        assert "strings_raw" in tables
        assert "function_analysis_errors" in tables

    def test_strings_only_includes_only_strings(self):
        tables = self._get_export_tables({"strings"})
        assert tables == {"strings_raw"}

    def test_cfg_only_includes_cfg_and_errors(self):
        tables = self._get_export_tables({"cfg"})
        assert tables == {"cfg_functions", "function_analysis_errors"}

    def test_decompilation_only_tables(self):
        tables = self._get_export_tables({"decompilation"})
        assert tables == {"decompiled_content", "decompiled_refs", "function_analysis_errors"}

    def test_disassembly_only_tables(self):
        tables = self._get_export_tables({"disassembly"})
        assert tables == {
            "disassembled_content", "disassembled_refs",
            "function_similarity_metrics", "function_analysis_errors"
        }

    def test_llil_only_tables(self):
        tables = self._get_export_tables({"llil"})
        assert tables == {"llil_content", "llil_refs", "function_analysis_errors"}

    def test_combined_cfg_strings_tables(self):
        tables = self._get_export_tables({"cfg", "strings"})
        assert tables == {"cfg_functions", "strings_raw", "function_analysis_errors"}

    def test_no_errors_table_for_strings_only(self):
        """Error table should NOT be included when only strings is selected (no per-function loop)."""
        tables = self._get_export_tables({"strings"})
        assert "function_analysis_errors" not in tables


# ============================================================================
# DecompileBinja Parameter Acceptance Tests
# ============================================================================

class TestDecompileBinjaDecompileModules:
    """Tests that DecompileBinja accepts and stores decompile_modules.

    Since DecompileBinja imports binaryninja (which requires blake3 etc),
    we test the default/init logic in isolation.
    """

    def test_default_decompile_modules(self):
        """decompile_modules defaults to {'all'} when None."""
        modules = None
        result = modules or {"all"}
        assert result == {"all"}

    def test_explicit_decompile_modules(self):
        """Explicit decompile_modules is preserved."""
        modules = {"cfg", "llil"}
        result = modules or {"all"}
        assert result == {"cfg", "llil"}

    def test_empty_set_becomes_all(self):
        """Empty set is falsy and defaults to {'all'}."""
        modules = set()
        result = modules or {"all"}
        assert result == {"all"}


# ============================================================================
# Integration-Style: analyze_binary() Per-Function Gating (Logic Tests)
# ============================================================================

class TestAnalyzeBinaryPerFunctionGating:
    """Test that the per-function extraction gating produces correct results structures.

    These test the logic patterns from analyze_binary() using mock data,
    verifying that:
    - Unselected modules produce empty result lists
    - Selected modules produce populated result lists
    - Disassembly always runs when any per-function module is selected
    - Cross-linkage None handling works when counterparts are skipped
    """

    def _simulate_per_function_results(self, decompile_modules, num_functions=3):
        """Simulate the per-function extraction loop from analyze_binary().

        Returns results dict with the same structure as analyze_binary().
        """
        run_all = "all" in decompile_modules
        run_strings = run_all or "strings" in decompile_modules
        run_decompilation = run_all or "decompilation" in decompile_modules
        run_disassembly = run_all or "disassembly" in decompile_modules
        run_llil = run_all or "llil" in decompile_modules
        run_cfg = run_all or "cfg" in decompile_modules
        need_per_function = run_decompilation or run_disassembly or run_llil or run_cfg

        results = {
            "decompiled": [],
            "disassembled": [],
            "cfg": [],
            "llil": [],
            "errors": [],
            "strings": [],
        }

        if run_strings:
            results["strings"] = [{"string": f"str_{i}"} for i in range(5)]

        if not need_per_function:
            return results

        for i in range(num_functions):
            hlil_json = {"decompiled_function_hash": f"hlil_{i}"} if run_decompilation else None
            disass_json = {"disassembled_function_hash": f"disass_{i}", "disassembled_function_name": f"func_{i}", "disassembled_function_address": i * 100}  # always
            cfg_json = {"function_address": i * 100, "cyclomatic_complexity": 5} if run_cfg else None
            lowlevel_json = {"sha256_llil": f"llil_{i}", "tlsh_llil": "def", "minhash": [1, 2]} if run_llil else None

            # Simulate cross-linkage (same pattern as real code)
            if hlil_json and disass_json:
                hlil_json["disassembled_function_hash"] = disass_json["disassembled_function_hash"]
                disass_json["decompiled_function_hash"] = hlil_json["decompiled_function_hash"]
                results["decompiled"].append(hlil_json)
                if run_disassembly:
                    results["disassembled"].append(disass_json)
            elif hlil_json:
                hlil_json["disassembled_function_hash"] = None
                results["decompiled"].append(hlil_json)
            elif disass_json:
                disass_json["decompiled_function_hash"] = None
                if run_disassembly:
                    results["disassembled"].append(disass_json)

            if lowlevel_json and disass_json:
                lowlevel_json["disassembled_function_hash"] = disass_json["disassembled_function_hash"]
                disass_json["tlsh_llil"] = lowlevel_json.get("tlsh_llil")
                disass_json["minhash"] = lowlevel_json.get("minhash")
            elif lowlevel_json:
                lowlevel_json["disassembled_function_hash"] = None
            elif disass_json:
                disass_json["tlsh_llil"] = None
                disass_json["minhash"] = None

            if lowlevel_json:
                results["llil"].append(lowlevel_json)

            if cfg_json and disass_json:
                cfg_json["disassembled_function_hash"] = disass_json["disassembled_function_hash"]
                disass_json["cyclomatic_complexity"] = cfg_json.get("cyclomatic_complexity")
                results["cfg"].append(cfg_json)
            elif cfg_json:
                cfg_json["disassembled_function_hash"] = None
                results["cfg"].append(cfg_json)

            if disass_json and "cyclomatic_complexity" not in disass_json:
                disass_json["cyclomatic_complexity"] = None

        return results

    def test_all_populates_everything(self):
        r = self._simulate_per_function_results({"all"}, 3)
        assert len(r["decompiled"]) == 3
        assert len(r["disassembled"]) == 3
        assert len(r["cfg"]) == 3
        assert len(r["llil"]) == 3
        assert len(r["strings"]) == 5

    def test_strings_only_populates_strings(self):
        r = self._simulate_per_function_results({"strings"}, 3)
        assert len(r["strings"]) == 5
        assert len(r["decompiled"]) == 0
        assert len(r["disassembled"]) == 0
        assert len(r["cfg"]) == 0
        assert len(r["llil"]) == 0

    def test_cfg_only_populates_cfg_no_disassembly_export(self):
        """With only 'cfg' selected, cfg list is populated but disassembled is empty
        (disassembly runs internally but not exported)."""
        r = self._simulate_per_function_results({"cfg"}, 3)
        assert len(r["cfg"]) == 3
        assert len(r["disassembled"]) == 0  # Not selected for export
        assert len(r["decompiled"]) == 0
        assert len(r["llil"]) == 0
        assert len(r["strings"]) == 0

    def test_cfg_has_disassembled_function_hash_linkage(self):
        """CFG entries get disassembled_function_hash from backbone disassembly."""
        r = self._simulate_per_function_results({"cfg"}, 2)
        for cfg in r["cfg"]:
            assert cfg["disassembled_function_hash"] is not None
            assert cfg["disassembled_function_hash"].startswith("disass_")

    def test_decompilation_only_has_none_disassembly_linkage_when_no_disasm(self):
        """When only decompilation selected, disassembled still runs (backbone)
        so linkage is still available."""
        r = self._simulate_per_function_results({"decompilation"}, 2)
        assert len(r["decompiled"]) == 2
        # Disassembly runs as backbone, so linkage hash is present
        for d in r["decompiled"]:
            assert d["disassembled_function_hash"] is not None

    def test_disassembly_without_llil_has_none_fuzzy_hashes(self):
        """When LLIL is not selected, disassembly records have None fuzzy hashes."""
        r = self._simulate_per_function_results({"disassembly"}, 2)
        for d in r["disassembled"]:
            assert d["tlsh_llil"] is None
            assert d["minhash"] is None

    def test_disassembly_without_decompilation_has_none_decompiled_hash(self):
        """When decompilation is not selected, disassembly has None decompiled_function_hash."""
        r = self._simulate_per_function_results({"disassembly"}, 2)
        for d in r["disassembled"]:
            assert d["decompiled_function_hash"] is None

    def test_disassembly_without_cfg_has_none_cyclomatic(self):
        """When CFG is not selected, disassembly has None cyclomatic_complexity."""
        r = self._simulate_per_function_results({"disassembly"}, 2)
        for d in r["disassembled"]:
            assert d["cyclomatic_complexity"] is None

    def test_all_linkage_populated(self):
        """When all modules run, all cross-linkage fields are populated."""
        r = self._simulate_per_function_results({"all"}, 2)
        for d in r["disassembled"]:
            assert d["decompiled_function_hash"] is not None
            assert d["tlsh_llil"] is not None
            assert d["cyclomatic_complexity"] is not None
        for h in r["decompiled"]:
            assert h["disassembled_function_hash"] is not None
        for c in r["cfg"]:
            assert c["disassembled_function_hash"] is not None
        for ll in r["llil"]:
            assert ll["disassembled_function_hash"] is not None


# ============================================================================
# IOC Extraction Gating by decompile_modules
# ============================================================================

class TestIOCExtractionGating:
    """Tests that IOC extraction only runs when its data sources are present.

    IOCExtractorFromResults consumes in-memory analysis_results['strings']
    and analysis_results['decompiled']. It runs automatically (implicit
    dependency) when 'decompilation' or 'strings' modules produce data.
    It is NOT a standalone selectable module.
    """

    @staticmethod
    def _is_ioc_relevant(decompile_modules):
        """Replicate the gating logic from workers.py."""
        return (
            not decompile_modules
            or "all" in decompile_modules
            or "decompilation" in decompile_modules
            or "strings" in decompile_modules
        )

    def test_all_triggers_ioc(self):
        assert self._is_ioc_relevant({"all"}) is True

    def test_decompilation_triggers_ioc(self):
        assert self._is_ioc_relevant({"decompilation"}) is True

    def test_strings_triggers_ioc(self):
        assert self._is_ioc_relevant({"strings"}) is True

    def test_decompilation_and_strings_triggers_ioc(self):
        assert self._is_ioc_relevant({"decompilation", "strings"}) is True

    def test_cfg_only_skips_ioc(self):
        assert self._is_ioc_relevant({"cfg"}) is False

    def test_disassembly_only_skips_ioc(self):
        assert self._is_ioc_relevant({"disassembly"}) is False

    def test_llil_only_skips_ioc(self):
        assert self._is_ioc_relevant({"llil"}) is False

    def test_cfg_and_disassembly_skips_ioc(self):
        assert self._is_ioc_relevant({"cfg", "disassembly"}) is False

    def test_cfg_and_llil_skips_ioc(self):
        assert self._is_ioc_relevant({"cfg", "llil"}) is False

    def test_cfg_and_decompilation_triggers_ioc(self):
        """If decompilation is included alongside cfg, IOC should run."""
        assert self._is_ioc_relevant({"cfg", "decompilation"}) is True

    def test_disassembly_and_strings_triggers_ioc(self):
        """If strings is included alongside disassembly, IOC should run."""
        assert self._is_ioc_relevant({"disassembly", "strings"}) is True

    def test_none_modules_triggers_ioc(self):
        """When decompile_modules is None (default), IOC should run."""
        assert self._is_ioc_relevant(None) is True

    def test_empty_set_triggers_ioc(self):
        """When decompile_modules is empty set, IOC should run (falsy)."""
        assert self._is_ioc_relevant(set()) is True