James Clarke

25 papers A* 5B 2Journal 8Unranked 9
YearRankTypeTitle / Venue / Authors
2025 J jnl
IEEE Trans. Vis. Comput. Graph.
Andreas Christodoulides, Gary K. L. Tam, James Clarke, Richard Smith, Jon Horgan, Nicholas Micallef, Jeremy Morley, Nelly Villamizar, Sean Peter Walton
2014 J jnl
Secur. Commun. Networks
Hamza Ghani, Abdelmajid Khelil, Neeraj Suri, György Csertán, László Gönczy, Gábor Urbanics, James Clarke
2014 J jnl
Secur. Commun. Networks
James Clarke, Stefanos Gritzalis, Jianying Zhou, Rodrigo Roman
2014 J jnl
Secur. Commun. Networks
James Clarke, Stefanos Gritzalis, Jianying Zhou, Rodrigo Roman
2013 conf
TAC
Yuval Merhav, Joel Barry, James Clarke, David Murgatroyd
2012 B conf
LREC
James Clarke, Vivek Srikumar, Mark Sammons, Dan Roth
2012 conf
TAC
James Clarke, Yuval Merhav, Ghalib Suleiman, Shuai Zheng, David Murgatroyd
2012 conf
SECURIT
James Clarke, Rodrigo Roman Castro, Abhishek Sharma, Javier López, Neeraj Suri
2012 J jnl
Pers. Ubiquitous Comput.
Ofer Bergman, Andreas Komninos, Dimitrios Liarokapis, James Clarke
2011 conf
SysSec@DIMVA
James Clarke, Neeraj Suri, Michel Riguidel, Aljosa Pasic
2011 A* conf
ACL
Dan Goldwasser, Roi Reichart, James Clarke, Dan Roth
2011 J jnl
ACM Journal on Computing and Cultural Heritage
Victor Obonyo, Douglas Troy, Daryl Baldwin, James Clarke
2011 conf
MLSLP
Ming-Wei Chang, James Clarke, Dan Goldwasser, Lev-Arie Ratinov, Vivek Srikumar, Dan Roth
2010 J jnl
Comput. Linguistics
James Clarke, Mirella Lapata
2010 B conf
CoNLL
James Clarke, Dan Goldwasser, Ming-Wei Chang, Dan Roth
2009 A* conf
EMNLP
Jacob Eisenstein, James Clarke, Dan Goldwasser, Dan Roth
2009 conf
HLT-NAACL (Short Papers)
Sebastian Riedel, James Clarke
2008 J jnl
J. Artif. Intell. Res.
James Clarke, Mirella Lapata
2008
James Clarke
2007 conf
EMNLP-CoNLL
James Clarke, Mirella Lapata
2006 A* conf
ACL
James Clarke, Mirella Lapata
2006 A* conf
EMNLP
Sebastian Riedel, James Clarke
2006 A* conf
ACL
James Clarke, Mirella Lapata
2006 conf
ISVC (2)
James Clarke, Sarah Barman, Paolo Remagnino, Ken Bailey, Don Kirkup, Simon Mayo, Paul Wilkin
2000 conf
INTERWORKING
James Clarke, Stephen Butler, George Kartsounis, Simela Topouzidou
tests/unit/test_decompile_strings.py
← Index tests/unit/test_decompile_strings.py python
"""Unit tests for bninja/analysis/strings.py — StringAnalysis."""
import pytest
import math
from unittest.mock import MagicMock


# StringAnalysis has no binaryninja imports, just collections and math
from redb.extractors.decompiler.bninja.analysis.strings import StringAnalysis


# ============================================================================
# Helper mocks
# ============================================================================

class MockStringEntry:
    """Mock for a Binary Ninja string reference."""
    def __init__(self, value, raw=None, start=0, length=0, type_name="Utf8String"):
        self.value = value
        self.raw = raw if raw is not None else (value.encode("utf-8") if isinstance(value, str) else value)
        self.start = start
        self.length = length if length else len(self.raw)
        self.type = MagicMock()
        self.type.name = type_name


class MockBinaryView:
    """Mock binary view with a strings list."""
    def __init__(self, strings=None):
        self.strings = strings or []


# ============================================================================
# 6a. StringAnalysis
# ============================================================================


class TestStringAnalysisEntropy:
    def setup_method(self):
        self.sa = StringAnalysis(bv=MockBinaryView(), functions=[])

    def test_entropy_empty_string(self):
        assert self.sa.entropy("") == 0.0

    def test_entropy_single_char(self):
        assert self.sa.entropy("aaaa") == 0.0

    def test_entropy_uniform_distribution(self):
        # "abcd" -> 4 unique chars, each p=1/4, entropy = log2(4) = 2.0
        result = self.sa.entropy("abcd")
        assert result == pytest.approx(2.0)

    def test_entropy_binary_string(self):
        # "ab" -> 2 unique chars, each p=1/2, entropy = log2(2) = 1.0
        result = self.sa.entropy("ab")
        assert result == pytest.approx(1.0)


class TestStringAnalysisAnalyze:
    def test_analyze_deduplication(self):
        """Duplicate (string, encoding) pairs -> only first kept."""
        entries = [
            MockStringEntry("hello", start=100, type_name="Utf8String"),
            MockStringEntry("hello", start=200, type_name="Utf8String"),
        ]
        bv = MockBinaryView(strings=entries)
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert len(result) == 1
        assert result[0]["string_offset"] == 100

    def test_analyze_sorted_by_address(self):
        """First occurrence (lowest offset) is the one kept."""
        entries = [
            MockStringEntry("world", start=500, type_name="Utf8String"),
            MockStringEntry("world", start=100, type_name="Utf8String"),
        ]
        bv = MockBinaryView(strings=entries)
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert len(result) == 1
        # The analyze() sorts by start, so 100 comes first
        assert result[0]["string_offset"] == 100

    def test_analyze_empty_bv(self):
        bv = MockBinaryView(strings=[])
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert result == []

    def test_analyze_output_schema(self):
        entries = [MockStringEntry("test_string", start=0, type_name="Utf8String")]
        bv = MockBinaryView(strings=entries)
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert len(result) == 1
        r = result[0]
        required_keys = [
            "string",
            "string_raw",
            "string_encoding",
            "string_offset",
            "string_length",
            "string_raw_length",
            "string_entropy",
        ]
        for key in required_keys:
            assert key in r, f"Missing key: {key}"