Catherine Havasi

48 papers A* 2A 6B 5C 1Misc 4Journal 13Unranked 15
YearRankTypeTitle / Venue / Authors
2021 J jnl
CoRR
Pedro Colon-Hernandez, Catherine Havasi, Jason B. Alonso, Matthew Huggins, Cynthia Breazeal
2021 conf
ACL/IJCNLP (Findings)
Pedro Colon-Hernandez, Yida Xin, Henry Lieberman, Catherine Havasi, Cynthia Breazeal, Peter Chin
2021 J jnl
CoRR
Pedro Colon-Hernandez, Yida Xin, Henry Lieberman, Catherine Havasi, Cynthia Breazeal, Peter Chin
2019 B conf
K-CAP
Catherine Havasi
2017 A* conf
AAAI
Robyn Speer, Joshua Chin, Catherine Havasi
2016 J jnl
CoRR
Robyn Speer, Joshua Chin, Catherine Havasi
2013 ch.
The People's Web Meets NLP
Robyn Speer, Catherine Havasi
2013 J jnl
IEEE Intell. Syst.
Erik Cambria, Björn W. Schuller, Bing Liu, Haixun Wang, Catherine Havasi
2013 conf
HCI (29)
Kasia Hayden, Dan Novy, Catherine Havasi, V. Michael Bove Jr., Santiago Alfaro, Robyn Speer
2013 J jnl
IEEE Intell. Syst.
Erik Cambria, Björn W. Schuller, Yunqing Xia, Catherine Havasi
2013 J jnl
IEEE Intell. Syst.
Erik Cambria, Björn W. Schuller, Bing Liu, Haixun Wang, Catherine Havasi
2012 J jnl
ACM Trans. Interact. Intell. Syst.
Karthik Dinakar, Birago Jones, Catherine Havasi, Henry Lieberman, Rosalind W. Picard
2012 J jnl
Tiny Trans. Comput. Sci.
Robyn Speer, Catherine Havasi
2012 J jnl
ACM Trans. Interact. Intell. Syst.
Henry Lieberman, Catherine Havasi
2012 B conf
LREC
Robyn Speer, Catherine Havasi
2012 J jnl
Multim. Tools Appl.
Erik Cambria, Marco Grassi, Amir Hussain, Catherine Havasi
2012 Misc conf
FLAIRS
Erik Cambria, Catherine Havasi, Amir Hussain
2012 J jnl
AI Mag.
Catherine Havasi, Richard Borovoy, Boris Kizelshteyn, Polychronis Ypodimatopoulos, Jon Ferguson, Henry Holtzman, Andrew Lippman, Dan Schultz, Matthew Blackshaw, Greg T. Elliott
2011 Misc conf
FLAIRS
Kevin Gold, Catherine Havasi, Michael Anderson, Kenneth C. Arnold
2011 B conf
CogSci
Catherine Havasi, Robyn Speer
2011 J jnl
AI Mag.
Roger Azevedo, Gautam Biswas, Dan Bohus, Ted Carmichael, Mark A. Finlayson, Mirsad Hadzikadic, Catherine Havasi, Eric Horvitz, Takayuki Kanda, Oluwasanmi Koyejo, William F. Lawless, Douglas B. Lenat, Felipe Meneguzzi, Bilge Mutlu, Jean Oh, Roberto Pirrone, Antoine Raux, Donald A. Sofge, Gita Sukthankar, Benjamin Van Durme
2011 C conf
IAAI
Catherine Havasi, Richard Borovoy, Boris Kizelshteyn, Polychronis Ypodimatopoulos, Jon Ferguson, Henry Holtzman, Andrew Lippman, Dan Schultz, Matthew Blackshaw, Greg T. Elliott, Chaki Ng
2010 conf
AAAI Fall Symposium: Commonsense Knowledge
Catherine Havasi, Robyn Speer, Justin Holmgren
2010 conf
AAAI Fall Symposium: Commonsense Knowledge
Catherine Havasi, Robyn Speer, James Pustejovsky
2010 conf
SciPy
Robyn Speer, Kenneth C. Arnold, Catherine Havasi
2010 conf
Metacognition for Robust Social Systems
Jason Bernardino Alonso, Kenneth C. Arnold, Catherine Havasi
2010 A conf
IUI
Robyn Speer, Catherine Havasi, K. Nichole Treadway, Henry Lieberman
2010 conf
Collaboratively-Built Knowledge Sources and AI
Catherine Havasi, Robyn Speer, Kenneth C. Arnold, Henry Lieberman, Jason B. Alonso, Jesse Moeller
2010 conf
AAAI Fall Symposium: Commonsense Knowledge
Catherine Havasi, Douglas B. Lenat, Benjamin Van Durme
2010 conf
AAAI Fall Symposium: Commonsense Knowledge
Catherine Havasi, Douglas B. Lenat, Benjamin Van Durme
2010 conf
Collaboratively-Built Knowledge Sources and AI
Catherine Havasi, Jason B. Alonso, Robyn Speer
2010 conf
AAAI Fall Symposium: Commonsense Knowledge
Erik Cambria, Robyn Speer, Catherine Havasi, Amir Hussain
2010 conf
KES (4)
Erik Cambria, Amir Hussain, Catherine Havasi, Chris Eckl
2010 Misc conf
FLAIRS
Robyn Speer, Catherine Havasi, Harshit Surana
2009 A conf
IUI
Robyn Speer, Jayant Krishnamurthy, Catherine Havasi, Dustin A. Smith, Henry Lieberman, Kenneth C. Arnold
2009 A conf
IUI
Catherine Havasi, Henry Lieberman, Erik T. Mueller
2009 conf
COST 2101/2102 Conference
Erik Cambria, Amir Hussain, Catherine Havasi, Chris Eckl
2009 J jnl
IEEE Intell. Syst.
Catherine Havasi, Robyn Speer, James Pustejovsky, Henry Lieberman
2009 A conf
UMAP
Jason B. Alonso, Catherine Havasi, Henry Lieberman
2009 conf
COST 2102 Training School
Erik Cambria, Amir Hussain, Catherine Havasi, Chris Eckl
2008 A* conf
AAAI
Robyn Speer, Catherine Havasi, Henry Lieberman
2008 A conf
IUI
Andrew S. Gordon, Catherine Havasi, Mathias Lux, Markus Strohmaier
2008 ed.
CSKGOI
Andrew S. Gordon, Catherine Havasi, Mathias Lux, Markus Strohmaier
2007 A conf
IUI
Catherine Havasi, Henry Lieberman
2006 B conf
LREC
Catherine Havasi, James Pustejovsky, Marc Verhagen
2006 conf
SIGDIAL Workshop
Ben Wellner, James Pustejovsky, Catherine Havasi, Anna Rumshisky, Roser Saurí
2006 Misc conf
FLAIRS
Anna Rumshisky, Patrick Hanks, Catherine Havasi, James Pustejovsky
2006 B conf
LREC
James Pustejovsky, Catherine Havasi, Jessica Littman, Anna Rumshisky, Marc Verhagen
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()