Skip to content

Commit 9fc7f21

Browse files
committed
fix: Fix censor_string() behavior on short strings
When called with a one-char string, censor_string() would return the same char doubled (so `censor_string("a")` would return "aa"). The behavior was also not good on 2-char string: it would leave the string unchanged, and on 3-char string it would hide only the middle char. Change this to make sure that: - 1 & 2 char strings are fully censored - 2 chars out of 3 are censored in a 3 char string Fixes #1086
1 parent 99cf736 commit 9fc7f21

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Fixed
2+
3+
- Fixed a bug in the way ggshield obfuscated secrets that caused a crash for short secrets (#1086).

ggshield/core/filter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ def censor_string(text: str) -> str:
114114
:return: the text censored
115115
"""
116116
len_match = len(text)
117+
118+
# Special cases for short lengths
119+
if len_match <= 2:
120+
return "*" * len_match
121+
if len_match == 3:
122+
return f"**{text[2]}"
123+
117124
start_privy_len = min(math.ceil(len_match / 6), MAXIMUM_CENSOR_LENGTH)
118125
end_privy_len = len_match - min(math.ceil(len_match / 6), MAXIMUM_CENSOR_LENGTH)
119126

tests/unit/core/test_filter.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pygitguardian.models import Match, PolicyBreak
77
from snapshottest import Snapshot
88

9-
from ggshield.core.filter import censor_match, get_ignore_sha
9+
from ggshield.core.filter import censor_match, censor_string, get_ignore_sha
1010
from tests.unit.conftest import (
1111
_MULTILINE_SECRET,
1212
_MULTIPLE_SECRETS_SCAN_RESULT,
@@ -116,3 +116,18 @@ def test_censor_match(input_match: Match, expected_value: str) -> None:
116116
value = censor_match(input_match)
117117
assert len(value) == len(input_match.match)
118118
assert value == expected_value
119+
120+
121+
@pytest.mark.parametrize(
122+
["text", "expected"],
123+
(
124+
("hello world", "he*** ***ld"),
125+
("abcd", "a**d"),
126+
("abc", "**c"),
127+
("ab", "**"),
128+
("a", "*"),
129+
),
130+
)
131+
def test_censor_string(text: str, expected: str) -> None:
132+
censored = censor_string(text)
133+
assert censored == expected

0 commit comments

Comments
 (0)