Manjesh Kumar Hanawal

145 papers A* 9A 2B 13C 1Misc 22Journal 81Unranked 16
YearRankTypeTitle / Venue / Authors
2026 Misc conf
COMSNETS
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2026 J jnl
CoRR
Divya Jyoti Bajpai, Dhruv Bhardwaj, Soumya Roy, Tejas Duseja, Harsh Agarwal, Aashay Sandansing, Manjesh Kumar Hanawal
2026 J jnl
CoRR
Divya Jyoti Bajpai, Shubham Agarwal, Apoorv Saxena, Kuldeep Kulkarni, Subrata Mitra, Manjesh Kumar Hanawal
2026 Misc conf
COMSNETS
Debamita Ghosh, Manjesh Kumar Hanawal, Nikola Zlatanov
2026 Misc conf
COMSNETS
Anubhav Binit, Nitish Kumar, Manjesh Kumar Hanawal
2026 Misc conf
COMSNETS
Aditi Aralkar, Pankaj Chaudhary, Neminath Hubballi, Manjesh Kumar Hanawal
2026 Misc conf
COMSNETS
Arun Verma, Manjesh Kumar Hanawal, Arun Rajkumar
2026 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Arun Rajkumar
2026 J jnl
IEEE Open J. Commun. Soc.
Damir Salakhov, Nikola Zlatanov, Alexey A. Frolov, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 A* conf
ICLR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 Misc conf
ICISS
Prakhar Paliwal, Atul Kabra, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Prakhar Paliwal, Atul Kabra, Manjesh Kumar Hanawal
2025 conf
ICC
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Rashmi Kamran, Mahesh Ganesh Bhat, Pranav Jha, Shana Moothedath, Manjesh Kumar Hanawal, Prasanna Chaporkar
2025 conf
ACL (Findings)
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 conf
IJCNLP-AACL (long papers)
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 Misc conf
COMSNETS
Debamita Ghosh, Manjesh Kumar Hanawal, Nikola Zlatanov
2025 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2025 J jnl
IEEE Access
Dmitry Artemasov, Alexander Shmatok, Kirill Andreev, Alexey A. Frolov, Manjesh Kumar Hanawal, Nikola Zlatanov
2024 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2024 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2024 conf
EMNLP (Findings)
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2024 J jnl
IEEE Access
Nikola Zlatanov, Manjesh Kumar Hanawal, Alexey A. Frolov, Kirill Andreev
2024 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2024 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2024 J jnl
CoRR
Divya Jyoti Bajpai, Manjesh Kumar Hanawal
2024 conf
EACL (1)
Divya Jyoti Bajpai, Ayush Maheshwari, Manjesh Kumar Hanawal, Ganesh Ramakrishnan
2024 J jnl
CoRR
Divya Jyoti Bajpai, Ayush Maheshwari, Manjesh Kumar Hanawal, Ganesh Ramakrishnan
2024 J jnl
Trans. Mach. Learn. Res.
Debamita Ghosh, Manjesh Kumar Hanawal, Nikola Zlatanov
2024 J jnl
CoRR
Debamita Ghosh, Manjesh Kumar Hanawal, Nikola Zlatanov
2024 J jnl
CoRR
Divya Jyoti Bajpai, Aastha Jaiswal, Manjesh Kumar Hanawal
2023 B conf
WiOpt
Rahul Vaze, Manjesh Kumar Hanawal
2023 B conf
WiOpt
Fathima Zarin Faizal, Adway Girish, Manjesh Kumar Hanawal, Nikhil Karamchandani
2023 J jnl
CoRR
Fathima Zarin Faizal, Adway Girish, Manjesh Kumar Hanawal, Nikhil Karamchandani
2023 conf
AIMLSystems
Divya Jyoti Bajpai, Vivek Kumar Trivedi, Sohan L. Yadav, Manjesh Kumar Hanawal
2022 Misc conf
COMSNETS
Vinod S. Khandkar, Manjesh Kumar Hanawal
2022 Misc conf
COMSNETS
Adhokshaj Mishra, Animesh Roy, Manjesh Kumar Hanawal
2022 Misc conf
COMSNETS
Harsh Verma, Hritik Goel, Sumit Jagdish Darak, Manjesh Kumar Hanawal
2022 Misc conf
COMSNETS
Hitesh Gudwani, Manjesh Kumar Hanawal, Sharayu Moharir
2022 J jnl
IEEE Trans. Autom. Control.
Manjesh Kumar Hanawal, Sumit Jagdish Darak
2022 J jnl
IEEE Trans. Commun.
Santosh Fatale, Kavya Bhandari, Urvidh Narula, Sharayu Moharir, Manjesh Kumar Hanawal
2022 J jnl
CoRR
Adhokshaj Mishra, Manjesh Kumar Hanawal
2022 conf
AIMLSystems
Hari Narayan N. U, Manjesh Kumar Hanawal, Avinash Bhardwaj
2021 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Arun Rajkumar, Raman Sankaran
2021 Misc conf
COMSNETS
Vinod S. Khandkar, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Vinod S. Khandkar, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Rahul Vaze, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Adhokshaj Mishra, Animesh Roy, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Vinod S. Khandkar, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Sayan Chatterjee, Manjesh Kumar Hanawal
2021 J jnl
IEEE Wirel. Commun. Lett.
Debamita Ghosh, Manjesh Kumar Hanawal, Nikola Zlatanov
2021 J jnl
CoRR
Vinod S. Khandkar, Manjesh Kumar Hanawal
2021 Misc conf
COMSNETS
Anupam Singh, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Fehmina Malik, Manjesh Kumar Hanawal, Yezekael Hayel
2021 J jnl
Perform. Evaluation
Fehmina Malik, Manjesh Kumar Hanawal, Yezekael Hayel, Jayakrishnan Nair
2021 A* conf
NeurIPS
Arun Verma, Manjesh Kumar Hanawal
2021 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal
2021 B conf
IJCNN
Atul Sahay, Ayush Maheshwari, Ritesh Kumar, Ganesh Ramakrishnan, Manjesh Kumar Hanawal, Kavi Arya
2021 J jnl
CoRR
Atul Sahay, Ayush Maheshwari, Ritesh Kumar, Ganesh Ramakrishnan, Manjesh Kumar Hanawal, Kavi Arya
2020 B conf
WiOpt
Kavya Bhandari, Santosh Fatale, Urvidh Narula, Sharayu Moharir, Manjesh Kumar Hanawal
2020 J jnl
CoRR
Kavya Bhandari, Santosh Fatale, Urvidh Narula, Sharayu Moharir, Manjesh Kumar Hanawal
2020 J jnl
IEEE Trans. Cogn. Commun. Netw.
Manjesh Kumar Hanawal, Diep N. Nguyen, Marwan Krunz
2020 Misc conf
COMSNETS
Vinod S. Khandkar, Manjesh Kumar Hanawal
2020 B conf
DCOSS
Rohit Kumar, Sumit Jagdish Darak, Manjesh Kumar Hanawal
2020 J jnl
IEEE Syst. J.
Rohit Kumar, Sumit Jagdish Darak, Manjesh Kumar Hanawal, Ankit Yadav
2020 J jnl
CoRR
Sumit Jagdish Darak, Manjesh Kumar Hanawal
2020 J jnl
IEEE Trans. Cogn. Commun. Netw.
Manjesh Kumar Hanawal, Yezekael Hayel, Quanyan Zhu
2020 conf
SPCOM
Debamita Ghosh, Arun Verma, Manjesh Kumar Hanawal
2020 J jnl
CoRR
Debamita Ghosh, Arun Verma, Manjesh Kumar Hanawal
2020 J jnl
IEEE Trans. Mob. Comput.
Suneet Sawant, Rohit Kumar, Manjesh Kumar Hanawal, Sumit Jagdish Darak
2020 J jnl
CoRR
Debamita Ghosh, Manjesh Kumar Hanawal, Nikola Zlatanov
2020 A* conf
NeurIPS
Arun Verma, Manjesh Kumar Hanawal, Csaba Szepesvári, Venkatesh Saligrama
2020 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Csaba Szepesvári, Venkatesh Saligrama
2020 Misc conf
COMSNETS
Fehmina Malik, Manjesh Kumar Hanawal, Yezekael Hayel, Jayakrishnan Nair
2020 J jnl
SIGMETRICS Perform. Evaluation Rev.
Fehmina Malik, Manjesh Kumar Hanawal, Yezekael Hayel, Jayakrishnan Nair
2020 A* conf
INFOCOM
Arun Verma, Manjesh Kumar Hanawal
2020 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal
2020 C conf
ACML
Arun Verma, Manjesh Kumar Hanawal, Nandyala Hemachandra
2020 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Nandyala Hemachandra
2020 Misc conf
COMSNETS
Arun Verma, Manjesh Kumar Hanawal, Nandyala Hemachandra
2020 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Nandyala Hemachandra
2020 J jnl
IEEE/ACM Trans. Netw.
Fehmina Malik, Manjesh Kumar Hanawal, Yezekael Hayel
2019 A* conf
NeurIPS
Arun Verma, Manjesh Kumar Hanawal, Arun Rajkumar, Raman Sankaran
2019 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Arun Rajkumar, Raman Sankaran
2019 J jnl
IEEE Commun. Lett.
Rohit Kumar, Sumit Jagdish Darak, Manjesh Kumar Hanawal, Ajay K. Sharma, Rajiv K. Tripathi
2019 B conf
WiOpt
Arun Verma, Manjesh Kumar Hanawal, Rahul Vaze
2019 A* conf
INFOCOM
Harshvardhan Tibrewal, Sravan Patchala, Manjesh Kumar Hanawal, Sumit Jagdish Darak
2019 J jnl
CoRR
Harshvardhan Tibrewal, Sravan Patchala, Manjesh Kumar Hanawal, Sumit Jagdish Darak
2019 J jnl
IEEE Trans. Autom. Control.
Manjesh Kumar Hanawal, Hao Liu, Henghui Zhu, Ioannis Ch. Paschalidis
2019 J jnl
IEEE J. Sel. Areas Commun.
Sumit Jagdish Darak, Manjesh Kumar Hanawal
2019 A conf
AISTATS
Arun Verma, Manjesh Kumar Hanawal, Csaba Szepesvári, Venkatesh Saligrama
2019 J jnl
CoRR
Arun Verma, Manjesh Kumar Hanawal, Csaba Szepesvári, Venkatesh Saligrama
2019 Misc conf
COMSNETS
Vivek Nagraj Pandit, Mandar Datar, Manjesh Kumar Hanawal, Sharayu Moharir
2019 Misc conf
COMSNETS
Ayush Maheshwari, Ayush Goyal, Amit Kumar, Manjesh Kumar Hanawal, Ganesh Ramakrishnan
2019 Misc conf
COMSNETS
Fehmina Malik, Manjesh Kumar Hanawal
2019 J jnl
CoRR
Fehmina Malik, Manjesh Kumar Hanawal, Yezekael Hayel, Jayakrishnan Nair
2018 B conf
WiOpt
Manjesh Kumar Hanawal, Fehmina Malik, Yezekael Hayel
2018 J jnl
CoRR
Sumit Jagdish Darak, Manjesh Kumar Hanawal
2018 J jnl
SIGMETRICS Perform. Evaluation Rev.
Manjesh Kumar Hanawal, Sumit Jagdish Darak
2018 B conf
WiOpt
Suneet Sawant, Manjesh Kumar Hanawal, Sumit Darak, Rohit Kumar
2018 J jnl
CoRR
Manjesh Kumar Hanawal, Sumit Jagdish Darak
2018 B conf
WiOpt
Rohit Kumar, Ankit Yadav, Sumit Jagdish Darak, Manjesh Kumar Hanawal
2018 conf
COMAD/CODS
Arun Verma, Manjesh Kumar Hanawal
2018 conf
COMSNETS (Extended Selected Papers)
Salman Memon, Veeraruna Kavitha, Manjesh Kumar Hanawal, Eitan Altman, R. Devanand
2018 Misc conf
COMSNETS
Veeraruna Kavitha, Salman Memon, Manjesh Kumar Hanawal, Eitan Altman, R. Devanand
2017 J jnl
CoRR
Manjesh Kumar Hanawal, Hao Liu, Henghui Zhu, Ioannis Ch. Paschalidis
2017 B conf
WiOpt
Manjesh Kumar Hanawal, Yezekael Hayel, Quanyan Zhu
2017 A conf
AISTATS
Manjesh Kumar Hanawal, Csaba Szepesvári, Venkatesh Saligrama
2016 Misc conf
ICASSP
Manjesh Kumar Hanawal, Amir Leshem, Venkatesh Saligrama
2016 A* conf
INFOCOM
Manjesh Kumar Hanawal, Diep N. Nguyen, Marwan Krunz
2016 J jnl
IEEE Trans. Mob. Comput.
Manjesh Kumar Hanawal, Mohammad J. Abdel-Rahman, Marwan Krunz
2016 conf
CDC
Manjesh Kumar Hanawal, Hao Liu, Henghui Zhu, Ioannis Ch. Paschalidis
2016 J jnl
CoRR
Manjesh Kumar Hanawal, Csaba Szepesvári, Venkatesh Saligrama
2015 J jnl
CoRR
Manjesh Kumar Hanawal, Amir Leshem, Venkatesh Saligrama
2015 A* conf
ICML
Manjesh Kumar Hanawal, Venkatesh Saligrama, Michal Valko, Rémi Munos
2015 J jnl
CoRR
Manjesh Kumar Hanawal, Venkatesh Saligrama, Michal Valko, Rémi Munos
2015 conf
Allerton
Manjesh Kumar Hanawal, Venkatesh Saligrama
2015 Misc conf
ICASSP
Manjesh Kumar Hanawal, Venkatesh Saligrama
2015 J jnl
IEEE Access
Eitan Altman, Cengis Hasan, Manjesh Kumar Hanawal, Shlomo Shamai Shitz, Jean-Marie Gorce, Rachid El Azouzi, Laurent Roullet
2014 B conf
WiOpt
Manjesh Kumar Hanawal, Mohammad Abdel-Rahman, Marwan Krunz
2014 J jnl
ACM Trans. Internet Techn.
Eitan Altman, Manjesh Kumar Hanawal, Rajesh Sundaresan
2013
Manjesh Kumar Hanawal
2013 conf
ASMTA
Sushma Patil, Eitan Altman, Manjesh Kumar Hanawal, Julio Rojas-Mora
2013 J jnl
CoRR
Manjesh Kumar Hanawal, Eitan Altman
2013 B conf
WiOpt
Manjesh Kumar Hanawal, Eitan Altman
2012 J jnl
SIGMETRICS Perform. Evaluation Rev.
Manjesh Kumar Hanawal, Eitan Altman, Rajesh Sundaresan
2012 J jnl
CoRR
Eitan Altman, Manjesh Kumar Hanawal, Rajesh Sundaresan
2012 J jnl
IEEE J. Sel. Areas Commun.
Manjesh Kumar Hanawal, Eitan Altman, François Baccelli
2012 conf
WONS
Manjesh Kumar Hanawal, Eitan Altman
2012 A* conf
INFOCOM
Manjesh Kumar Hanawal, Eitan Altman, François Baccelli
2011 J jnl
IEEE Trans. Inf. Theory
Manjesh Kumar Hanawal, Rajesh Sundaresan
2011 J jnl
CoRR
Eitan Altman, Julio Rojas-Mora, Sulan Wong, Manjesh Kumar Hanawal, Yuedong Xu
2011 conf
GAMENETS
Eitan Altman, Julio Rojas-Mora, Sulan Wong, Manjesh Kumar Hanawal, Yuedong Xu
2011 conf
GAMENETS
Manjesh Kumar Hanawal, Eitan Altman, Rachid El Azouzi, Balakrishna J. Prabhu
2011 J jnl
CoRR
Manjesh Kumar Hanawal, Eitan Altman, François Baccelli
2011 J jnl
IEEE Trans. Inf. Theory
Manjesh Kumar Hanawal, Rajesh Sundaresan
2011 J jnl
SIGMETRICS Perform. Evaluation Rev.
Eitan Altman, Manjesh Kumar Hanawal, Rachid El Azouzi, Shlomo Shamai
2010 J jnl
CoRR
Manjesh Kumar Hanawal, Rajesh Sundaresan
2010 J jnl
CoRR
Manjesh Kumar Hanawal, Rajesh Sundaresan
2009 B conf
ISIT
Rajesh Sundaresan, Manjesh Kumar Hanawal
tests/unit/test_decompile_medium_level.py
← Index tests/unit/test_decompile_medium_level.py python
# tests/unit/test_decompile_medium_level.py
"""Unit tests (mocked BN) for bninja/analysis/medium_level.py
   and bninja/analysis/medium_level_normalization.py."""
# tests/unit/test_decompile_medium_level.py
import sys
from unittest.mock import MagicMock, patch

# Installa gli stubs BN
from tests.unit.conftest_binja_stubs import install_binja_stubs
install_binja_stubs()

# ── Definisci MockMLILInstruction PRIMA di importare il modulo ──
class MockMLILInstruction:
    def __init__(self, operation, address=0, operands=None):
        self.operation = operation
        self.address = address
        self.operands = operands or []

# ── Patcha il modulo BN in modo che isinstance() funzioni ──
sys.modules["binaryninja"].MediumLevelILInstruction = MockMLILInstruction
sys.modules["binaryninja"].SSAVariable = type("SSAVariable", (), {})
sys.modules["binaryninja"].Variable = type("Variable", (), {})
sys.modules["binaryninja"].ILIntrinsic = type("ILIntrinsic", (), {})

# Ora importa il modulo — vede già i tipi corretti
from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
    MediumLevelNormalization,
)	

class MockMLILFunction:
    def __init__(self, instructions):
        self._instructions = instructions

    @property
    def instructions(self):
        return iter(self._instructions)

    @property
    def basic_blocks(self):
        # one block containing all instructions, good enough for MinHasher
        block = MagicMock()
        block.__iter__ = lambda self_: iter([])  # not used by MediumLevelAnalysis
        return [block]


class MockFunction:
    def __init__(self, name="func", start=0x1000, mlil=None):
        self.name = name
        self.start = start
        self.mlil = mlil



class TestMediumLevelNormalization:
    def setup_method(self):
        from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
            MediumLevelNormalization,
        )
        self.norm = MediumLevelNormalization()

    def test_normalize_skeleton_single_instruction(self):
        il = MockMLILInstruction(operation=42, operands=[])
        result = self.norm.normalize_instruction_all_levels(il)
        assert result == [42]

    def test_normalize_skeleton_nested(self):
        inner = MockMLILInstruction(operation=7, operands=[])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [1, 7]

    def test_normalize_skeleton_with_list_operand(self):
        inner_a = MockMLILInstruction(operation=10, operands=[])
        inner_b = MockMLILInstruction(operation=11, operands=[])
        outer = MockMLILInstruction(operation=2, operands=[[inner_a, inner_b]])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [2, 10, 11]

    def test_normalize_skeleton_none(self):
        result = self.norm.normalize_instruction_all_levels(None)
        # collect on None should leave ops empty
        assert result == []

    def test_normalize_typed_appends_leaf_types(self):
        # operand is a plain int -> "CONST"
        il = MockMLILInstruction(operation=3, operands=[42])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [3, "CONST"]

    def test_normalize_typed_bool_before_int(self):
        # bool must be detected before int (since bool is an int subclass)
        il = MockMLILInstruction(operation=4, operands=[True])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [4, "BOOL"]

    def test_normalize_typed_float(self):
        il = MockMLILInstruction(operation=5, operands=[1.5])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [5, "FLOAT_CONST"]

    def test_normalize_typed_str(self):
        il = MockMLILInstruction(operation=6, operands=["hello"])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [6, "STR"]

    def test_normalize_typed_unknown_falls_back_to_typename(self):
        class Weird:
            pass
        il = MockMLILInstruction(operation=8, operands=[Weird()])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [8, "WEIRD"]

    def test_normalize_typed_nested_mlil(self):
        inner = MockMLILInstruction(operation=99, operands=[7])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instr_with_operands(outer)
        assert result == [1, 99, "CONST"]

    def test_normalize_typed_list_mixed(self):
        inner = MockMLILInstruction(operation=50, operands=[])
        il = MockMLILInstruction(operation=2, operands=[[inner, 99]])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [2, 50, "CONST"]


class TestMediumLevelAnalysis:
    def _make_analysis(self, instructions=None, mlil=True, start=0x1000):
        from redb.extractors.decompiler.bninja.analysis.medium_level import (
            MediumLevelAnalysis,
        )
        mlil_func = MockMLILFunction(instructions or []) if mlil else None
        func = MockFunction(name="testfunc", start=start, mlil=mlil_func)
        bv = MagicMock()
        return MediumLevelAnalysis(func, bv, MagicMock())

    def test_collect_returns_empty_when_no_mlil(self):
        a = self._make_analysis(mlil=False)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk == [] and sk_addr == [] and ty == [] and ty_addr == []

    def test_collect_skeleton_and_typed_basic(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()

        assert sk == [[1], [2]]
        assert ty == [[1], [2, "CONST"]]
        assert sk_addr == [(0, [1]), (4, [2])]
        assert ty_addr == [(0, [1]), (4, [2, "CONST"])]

    def test_collect_negative_offset_clamped_to_zero(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x900, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        _, sk_addr, _, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk_addr[0][0] == 0
        assert ty_addr[0][0] == 0

    def test_log_error_records_entry(self):
        a = self._make_analysis()
        a.log_error("boom", "fname", 0x1234, ValueError("x"), "loc")
        assert len(a.errors) == 1
        err = a.errors[0]
        assert err["function_name"] == "fname"
        assert err["function_address"] == "4660"  # hex 0x1234
        assert err["error_location"] == "loc"
        assert err["error_message"] == "boom"
        assert err["error_type"] == "ValueError"
        assert "timestamp" in err

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_returns_expected_keys(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = [1, 2, 3]

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        result, errors = a.analyze()

        expected_keys = {
            "function_address",
            "body_mlil_skeleton_vector",
            "sha256_mlil_skeleton",
            "tlsh_mlil_skeleton",
            "minhash_mlil_skeleton",
            "body_mlil_typed_vector",
            "sha256_mlil_typed",
            "tlsh_mlil_typed",
            "minhash_mlil_typed",
        }
        assert set(result.keys()) == expected_keys
        assert result["function_address"] == 0x1000
        assert result["minhash_mlil_skeleton"] == [1, 2, 3]
        assert result["minhash_mlil_typed"] == [1, 2, 3]
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_empty_mlil(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []
        a = self._make_analysis(mlil=False)
        result, errors = a.analyze()
        assert result["body_mlil_skeleton_vector"] == []
        assert result["body_mlil_typed_vector"] == []
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_sha256_differs_skeleton_vs_typed(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[42]),
            MockMLILInstruction(operation=2, address=0x1004, operands=["foo"]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[True]),
        ]
        a = self._make_analysis(instructions=instrs)
        result, _ = a.analyze()
        # skeleton ignores operand leaves, typed includes them -> different hashes
        assert result["sha256_mlil_skeleton"] != result["sha256_mlil_typed"]


class TestMinHasherMLILKinds:
    def _make_func(self, instrs):
        # MinHasher iterates basic_blocks then over each block
        block = MagicMock()
        block.__iter__ = lambda self_: iter(instrs)
        f = MagicMock()
        f.basic_blocks = [block]
        return f

    def test_mlil_skeleton_uses_medium_normalizer(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=i, operands=[]) for i in range(5)
        ]
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        result = hasher.calculateMinHash()
        # 5 instructions -> 3 trigrams -> non-empty signature
        assert result != []

    def test_typed_mlil_differs_from_skeleton(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=1, operands=[42]),
            MockMLILInstruction(operation=2, operands=["s"]),
            MockMLILInstruction(operation=3, operands=[True]),
            MockMLILInstruction(operation=4, operands=[1.5]),
        ]
        func = self._make_func(instrs)
        skel = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL).calculateMinHash()
        typed = MinHasher(seed=42, il_function=func, kind=TokenKind.TYPED_MLIL).calculateMinHash()
        # Same seed, same instructions, but typed has extra leaf tokens
        # -> hashes should generally differ
        assert skel != typed

    def test_mlil_too_few_instructions(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [MockMLILInstruction(operation=1, operands=[])] * 2
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        assert hasher.calculateMinHash() == []

    def test_unsupported_kind_raises(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import MinHasher
        func = self._make_func([])
        hasher = MinHasher(seed=42, il_function=func, kind="bogus")
        with pytest.raises(ValueError):
            hasher.calculateMinHash()