Mahyar Shahsavari

21 papers B 1Journal 13Unranked 5
YearRankTypeTitle / Venue / Authors
2025 J jnl
Array
Amirhossein Sadough, Mahyar Shahsavari, Mark Wijtvliet, Marcel van Gerven
2025 J jnl
Trans. Mach. Learn. Res.
Roel Koopman, Amirreza Yousefzadeh, Mahyar Shahsavari, Guangzhi Tang, Manolis Sifalakis
2025 J jnl
CoRR
Stijn Groenen, Marzieh Hassanshahi Varposhti, Mahyar Shahsavari
2025 J jnl
CoRR
Amirhossein Sadough, Mahyar Shahsavari, Mark Wijtvliet, Marcel van Gerven
2025 J jnl
Neural Networks
Mehrzad Karamimanesh, Ebrahim Abiri, Mahyar Shahsavari, Kourosh Hassanli, André van Schaik, Jason Eshraghian
2024 J jnl
CoRR
Marzieh Hassanshahi Varposhti, Mahyar Shahsavari, Marcel van Gerven
2024 J jnl
CoRR
Roel Koopman, Amirreza Yousefzadeh, Mahyar Shahsavari, Guangzhi Tang, Manolis Sifalakis
2024 J jnl
CoRR
Freek Hens, Mohammad Mahdi Dehshibi, Leila Bagheriye, Mahyar Shahsavari, Ana Tajadura-Jiménez
2024 conf
COINS
Paul Tiemeijer, Mahyar Shahsavari, Mahmood Fazlali
2023 J jnl
Array
Mahyar Shahsavari, David B. Thomas, Marcel van Gerven, Andrew D. Brown, Wayne Luk
2023 conf
COINS
Mohammadnavid Ghader, Bahar J. Farahani, Zahra Rezvani, Mahyar Shahsavari, Mahmood Fazlali
2022 conf
COINS
Habib Irani, Fatemeh Elahi, Mahmood Fazlali, Mahyar Shahsavari, Bahareh J. Farahani
2021 conf
ICONS
Mahyar Shahsavari, David B. Thomas, Andrew D. Brown, Wayne Luk
2020 B conf
IJCNN
Alexander Rast, Mahyar Shahsavari, Graeme M. Bragg, Mark Vousden, David B. Thomas, Andrew D. Brown
2019 ch.
Handbook of Memristor Networks
Mahyar Shahsavari, Philippe Devienne, Pierre Boulet
2018 J jnl
IEEE Trans. Multi Scale Comput. Syst.
Mahyar Shahsavari, Pierre Boulet
2017 J jnl
CoRR
Mahyar Shahsavari, Pierre Boulet
2016 conf
NANOARCH
Mahyar Shahsavari, Pierre Falez, Pierre Boulet
2016 J jnl
Microelectron. J.
Seyyed Ashkan Ebrahimi, Mohammad Reza Reshadinezhad, Ali Bohlooli, Mahyar Shahsavari
2016
Mahyar Shahsavari
2016 J jnl
CoRR
Mazdak Fatahi, Mahmood Ahmadi, Mahyar Shahsavari, Arash Ahmadi, Philippe Devienne
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}"