Karyn Moffatt

57 papers A* 14A 10B 2C 1Journal 20Unranked 10
YearRankTypeTitle / Venue / Authors
2025 J jnl
Commun. ACM
Maurício Fontana de Vargas, Jiamin Dai, Karyn Moffatt
2025 J jnl
ACM Trans. Access. Comput.
Muhe Yang, Karyn Moffatt
2024 A conf
ASSETS
Muhe Yang, Karyn Moffatt
2024 A* conf
CHI
Maurício Fontana de Vargas, Christina Yu, Howard C. Shane, Karyn Moffatt
2024 A* conf
CHI
Muhe Yang, Karyn Moffatt
2024 J jnl
ACM Trans. Web
Michael Cormier, Robin Cohen, Richard Mann, Karyn Moffatt, Daniel Vogel, Mengfei Liu, Shangshang Zheng
2024 A conf
ASSETS
Jiamin Dai, Benjamin M. Gorman, Garreth W. Tigwell, Helena Marie Lyhme, Belén Barros Pena, Karyn Moffatt, Celine Latulipe
2023 conf
W4A
Jiamin Dai, John Miedema, Sebastian Hernandez, Alexandra Sutton-Lalani, Karyn Moffatt
2023 J jnl
ACM Trans. Access. Comput.
Jiamin Dai, Karyn Moffatt
2023 J jnl
ACM Trans. Access. Comput.
Amira Ghenai, Philips Ayeni, Jing Yu, Robin Cohen, Karyn Moffatt
2023 J jnl
J. Libr. Inf. Sci.
Jiamin Dai, Joan C. Bartlett, Karyn Moffatt
2022 A conf
ASSETS
Maurício Fontana de Vargas, Jiamin Dai, Karyn Moffatt
2022 A* conf
CHI
Jiamin Dai, Karyn Moffatt, Jinglan Lin, Khai N. Truong
2021 conf
ACL/IJCNLP (1)
Maurício Fontana de Vargas, Karyn Moffatt
2021 A* conf
CHI
Jiamin Dai, Karyn Moffatt
2021 A* conf
CHI
Carolyn Pang, Zhiqin Collin Wang, Joanna McGrenere, Rock Leung, Jiamin Dai, Karyn Moffatt
2021 C conf
ICT4AWE
Amira Ghenai, Xueguang Ma, Robin Cohen, Karyn Moffatt, Andy Yang, Yipeng Ji
2020 A ed.
ASSETS
Tiago João Guerreiro, Hugo Nicolau, Karyn Moffatt
2020 J jnl
Inf.
Robin Cohen, Karyn Moffatt, Amira Ghenai, Andy Yang, Margaret Corwin, Gary Lin, Raymond Zhao, Yipeng Ji, Alexandre Parmentier, Jason P'ng, Wil Tan, Lachlan Gray
2020 conf
WI/IAT
Michael Cormier, Robin Cohen, Karyn Moffatt, Anthony Chan
2020 J jnl
ACM Trans. Access. Comput.
Karyn Moffatt
2020 A* conf
CHI
Jiamin Dai, Karyn Moffatt
2020 J jnl
Behav. Inf. Technol.
Carolyn Pang, Carman Neustaedter, Karyn Moffatt, Kate Hennessy, Rui Pan
2019 J jnl
ACM Trans. Access. Comput.
Afroza Sultana, Karyn Moffatt
2019 A conf
ASSETS
Zhiqin Collin Wang, Carolyn Pang, Karyn Moffatt, Rock Leung, Joanna McGrenere
2018 J jnl
Health Informatics J.
Rita Orji, Karyn Moffatt
2017 conf
UIST (Adjunct Volume)
Taciana Pontual Falcão, Xiaofeng Yong, Elisabeth Sulmont, Robert Douglas Ferguson, Karyn Moffatt
2017 J jnl
Interact. Comput.
Robert Douglas Ferguson, Emily Anne Crist, Karyn Moffatt
2017 J jnl
Univers. Access Inf. Soc.
Karyn Moffatt, Golnoosh Pourshahid, Ronald M. Baecker
2017 A* conf
CHI
Leah Findlater, Karyn Moffatt, Jon E. Froehlich, Meethu Malu, Joan Zhang
2017 A* conf
CHI
Leah Findlater, Joan Zhang, Jon E. Froehlich, Karyn Moffatt
2017 conf
CRV
Michael Cormier, Richard Mann, Karyn Moffatt, Robin Cohen
2016 B conf
WI
Michael Cormier, Richard Mann, Robin Cohen, Karyn Moffatt
2016 conf
CHI Extended Abstracts
William Jones, Victoria Bellotti, Robert G. Capra, Jesse David Dinneen, Gloria Mark, Catherine C. Marshall, Karyn Moffatt, Jaime Teevan, Maximus Van Kleek
2016 J jnl
Educ. Inf. Technol.
Carrie Demmans Epp, Rhonda McEwen, Rachelle Campigotto, Karyn Moffatt
2016 B ed.
Graphics Interface
Tiberiu Popa, Karyn Moffatt
2016 J jnl
Comput. Vis. Image Underst.
Michael Cormier, Karyn Moffatt, Robin Cohen, Richard Mann
2016 A conf
ASSETS
Kristin Williams, Karyn Moffatt, Jonggi Hong, Yasmeen Faroqi-Shah, Leah Findlater
2015 A* conf
CHI
Kristin Williams, Karyn Moffatt, Denise McCall, Leah Findlater
2013 conf
ASIST
Afroza Sultana, Karyn Moffatt
2013 J jnl
Interactions
Karyn Moffatt
2012 J jnl
Interactions
Ronald M. Baecker, Karyn Moffatt, Michael Massimi
2012 A conf
IUI
Carrie Demmans Epp, Justin Djordjevic, Shimu Wu, Karyn Moffatt, Ronald M. Baecker
2010 A* conf
CHI
Karyn Moffatt, Joanna McGrenere
2010 conf
Future Play
Nicholas Shim, Ronald Baecker, Jeremy P. Birnholtz, Karyn Moffatt
2009 A* conf
CHI
Leah Findlater, Karyn Moffatt, Joanna McGrenere, Jessica Q. Dawson
2009 J jnl
ACM Trans. Access. Comput.
Karyn Moffatt, Joanna McGrenere
2008 A conf
ASSETS
Karyn Moffatt, Sandra Yuen, Joanna McGrenere
2008 conf
CHI Extended Abstracts
Karyn Moffatt
2007 J jnl
ACM SIGACCESS Access. Comput.
Karyn Moffatt
2007 A conf
ASSETS
Karyn Moffatt, Joanna McGrenere
2006 A conf
ASSETS
Shari Trewin, Simeon Keates, Karyn Moffatt
2006 A* conf
CHI
Jordan L. Boyd-Graber, Sonya S. Nikolova, Karyn Moffatt, Kenrick C. Kin, Joshua Y. Lee, Lester W. Mackey, Marilyn Tremaine, Maria M. Klawe
2005 A* conf
CHI
Kimberly Tee, Karyn Moffatt, Leah Findlater, Eve MacGregor, Joanna McGrenere, Barbara Purves, Sidney S. Fels
2004 J jnl
ACM SIGACCESS Access. Comput.
Karyn Moffatt, Rhian Davies
2004 A* conf
CHI
Karyn Moffatt, Joanna McGrenere, Barbara Purves, Maria M. Klawe
2003 conf
CUU
Joanna McGrenere, Rhian Davies, Leah Findlater, Peter Graf, Maria M. Klawe, Karyn Moffatt, Barbara Purves, Sarah Yang
tests/unit/test_apk_method_extractor.py
← Index tests/unit/test_apk_method_extractor.py python
"""
Unit tests for APK method-level content extraction, hashing, and similarity.

Tests SHA-256 normalization, ssdeep/TLSH computation, obfuscation detection,
and Dalvik-to-Java type conversion.
"""
import pytest

pytestmark = [pytest.mark.unit, pytest.mark.apk, pytest.mark.decompile]


class TestHashingFunctions:
    """Tests for hashing utility functions."""

    def test_sha256_deterministic(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_sha256
        h1 = compute_sha256("invoke-virtual {p0}, Lcom/Foo;->bar()V")
        h2 = compute_sha256("invoke-virtual {p0}, Lcom/Foo;->bar()V")
        assert h1 == h2

    def test_sha256_hex_length(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_sha256
        assert len(compute_sha256("test")) == 64

    def test_sha256_different_inputs(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_sha256
        assert compute_sha256("aaa") != compute_sha256("bbb")

    def test_ssdeep_none_for_short(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_ssdeep
        assert compute_ssdeep("short") is None

    def test_tlsh_none_for_short(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_tlsh
        assert compute_tlsh("x") is None


class TestObfuscationDetection:
    """Tests for obfuscation indicator detection."""

    def test_short_method_name_single_char(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("a", "Lcom/Foo;", "", 10)
        assert r["short_method_name"] is True

    def test_short_method_name_two_chars(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("ab", "Lcom/Foo;", "", 10)
        assert r["short_method_name"] is True

    def test_normal_method_name(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("onCreate", "Lcom/Foo;", "", 10)
        assert r["short_method_name"] is False

    def test_short_class_name(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("foo", "Lcom/a;", "", 10)
        assert r["short_class_name"] is True

    def test_normal_class_name(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("foo", "Lcom/example/MainActivity;", "", 10)
        assert r["short_class_name"] is False

    def test_string_encryption_detected(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = (
            'const-string v0, "xyz"\n'
            'invoke-static {v0}, Lcom/Enc;->decrypt(Ljava/lang/String;)Ljava/lang/String;\n'
        )
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_string_encryption"] is True

    def test_no_string_encryption(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = 'const-string v0, "hello"\ninvoke-virtual {v0}, Ljava/lang/String;->length()I'
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_string_encryption"] is False

    def test_reflection_detected(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = 'invoke-virtual {v0, v1}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;'
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_reflection_calls"] is True

    def test_no_reflection(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = 'invoke-virtual {p0}, Lcom/Foo;->bar()V'
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_reflection_calls"] is False

    def test_excessive_goto_detected(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = "\n".join(["goto :label"] * 10)
        # threshold = max(5, 20*0.15=3) = 5, 10 > 5
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 20)
        assert r["excessive_goto_count"] is True

    def test_no_excessive_goto(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = "goto :label\nreturn-void"
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 100)
        assert r["excessive_goto_count"] is False

    def test_goto_16_counted(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = "\n".join(["goto/16 :label"] * 10)
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 20)
        assert r["excessive_goto_count"] is True


class TestDalvikTypeConversion:
    """Tests for Dalvik-to-Java type conversion."""

    def test_void(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("V") == "void"

    def test_primitives(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("I") == "int"
        assert dalvik_type_to_java("Z") == "boolean"
        assert dalvik_type_to_java("J") == "long"
        assert dalvik_type_to_java("F") == "float"
        assert dalvik_type_to_java("D") == "double"
        assert dalvik_type_to_java("B") == "byte"
        assert dalvik_type_to_java("S") == "short"
        assert dalvik_type_to_java("C") == "char"

    def test_object_type(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("Ljava/lang/String;") == "String"
        assert dalvik_type_to_java("Lcom/example/Foo;") == "Foo"

    def test_array_type(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("[I") == "int[]"
        assert dalvik_type_to_java("[Ljava/lang/String;") == "String[]"

    def test_empty_returns_void(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("") == "void"


class TestJavaPrototypeConversion:
    """Tests for method signature to Java prototype conversion."""

    def test_simple_method(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        assert dalvik_to_java_prototype("foo", "()V") == "void foo()"

    def test_method_with_params(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        result = dalvik_to_java_prototype("bar", "(ILjava/lang/String;)Z")
        assert result == "boolean bar(int, String)"

    def test_method_returning_object(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        result = dalvik_to_java_prototype("create", "()Lcom/example/Foo;")
        assert result == "Foo create()"

    def test_empty_signature(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        result = dalvik_to_java_prototype("m", "")
        assert "m()" in result


class TestDalvikParamParsing:
    """Tests for parsing Dalvik parameter descriptors."""

    def test_empty(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("") == []

    def test_single_primitive(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("I") == ["I"]

    def test_multiple_primitives(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("IZJ") == ["I", "Z", "J"]

    def test_single_object(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("Ljava/lang/String;") == ["Ljava/lang/String;"]

    def test_mixed(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        result = _parse_dalvik_params("ILjava/lang/String;Z")
        assert result == ["I", "Ljava/lang/String;", "Z"]

    def test_arrays(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        result = _parse_dalvik_params("[I[Ljava/lang/String;")
        assert result == ["[I", "[Ljava/lang/String;"]

    def test_two_objects(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        result = _parse_dalvik_params("Landroid/os/Bundle;Ljava/lang/String;")
        assert len(result) == 2