diff --git a/garak/probes/badchars.py b/garak/probes/badchars.py index 664ad5e78..cbb80eca6 100644 --- a/garak/probes/badchars.py +++ b/garak/probes/badchars.py @@ -383,6 +383,10 @@ def _select_positions( def _select_ascii(limit: int) -> List[str]: if limit is None or limit <= 0 or limit >= len(ASCII_PRINTABLE): return list(ASCII_PRINTABLE) + + if limit == 1: + return [ASCII_PRINTABLE[0]] + step = max(1, (len(ASCII_PRINTABLE) - 1) // (limit - 1)) selected = [ASCII_PRINTABLE[i] for i in range(0, len(ASCII_PRINTABLE), step)] return selected[:limit] diff --git a/tests/probes/test_probes_badchars.py b/tests/probes/test_probes_badchars.py new file mode 100644 index 000000000..a6333811c --- /dev/null +++ b/tests/probes/test_probes_badchars.py @@ -0,0 +1,21 @@ +"""Regression tests for the badchars probe ASCII variant cap.""" + +import pytest + +from garak.probes.badchars import ASCII_PRINTABLE, BadCharacters + + +@pytest.mark.parametrize( + ("limit", "expected_count"), + [ + (1, 1), + (2, 2), + (3, 3), + ], +) +def test_select_ascii_respects_small_limits(limit: int, expected_count: int) -> None: + selected = BadCharacters._select_ascii(limit) + + assert len(selected) == expected_count + assert selected[0] == ASCII_PRINTABLE[0] + assert all(character in ASCII_PRINTABLE for character in selected)