Skip to content

Commit

Permalink
fix: attribute error when logging non-strings (#711)
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardcooke53 committed Sep 19, 2023
1 parent 6b288f2 commit 75e6e48
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
5 changes: 5 additions & 0 deletions semantic_release/cli/masking_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ def filter(self, record: logging.LogRecord) -> bool:
return True

def mask(self, msg: str) -> str:
if not isinstance(msg, str):
log.debug( # type: ignore[unreachable]
"cannot mask object of type %s", type(msg)
)
return msg
for mask, values in self._redact_patterns.items():
repl_string = (
self.REPLACE_STR
Expand Down
57 changes: 42 additions & 15 deletions tests/unit/semantic_release/cli/test_masking_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ def default_masking_filter():
return MaskingFilter()


@pytest.fixture
def logging_output_stream():
return io.StringIO()


@pytest.fixture
def logger(logging_output_stream, default_masking_filter):
root = logging.getLogger()
root.setLevel(logging.DEBUG)
root.addHandler(logging.StreamHandler(logging_output_stream))
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

for h in root.handlers:
h.addFilter(default_masking_filter)

return log


@pytest.mark.parametrize(
"unwanted", [f(obj) for f in (repr, str) for obj in ("", None)]
)
Expand Down Expand Up @@ -183,24 +202,32 @@ def test_log_record_is_masked_with_nontrivial_args(default_masking_filter, rec,
logging.CRITICAL,
),
)
def test_log_messages_are_masked(default_masking_filter, log_level, tmp_path):
buffer = io.StringIO()

root = logging.getLogger()
root.setLevel(logging.DEBUG)
root.addHandler(logging.StreamHandler(buffer))
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

for h in root.handlers:
h.addFilter(default_masking_filter)

def test_log_messages_are_masked(
default_masking_filter, log_level, logging_output_stream, logger, tmp_path
):
for secret in _secrets:
default_masking_filter.add_mask_for(secret)

log.log(log_level, ", ".join("%s" for _ in _secrets), *_secrets)
for h in (*root.handlers, *log.handlers):
logger.log(log_level, ", ".join("%s" for _ in _secrets), *_secrets)

root = logging.getLogger()
for h in (*root.handlers, *logger.handlers):
h.flush()

written = buffer.getvalue()
written = logging_output_stream.getvalue()
assert all(secret not in written for secret in _secrets)


@pytest.mark.parametrize("obj", (object(), (), {}, AttributeError("whoopsie")))
def test_non_strings_are_returned(default_masking_filter, obj):
rec = LogRecord(
name=__name__,
level=logging.INFO,
pathname=__file__,
lineno=10,
args=(),
msg=obj,
exc_info=None,
)

assert default_masking_filter.mask(rec.getMessage()) == str(obj)

0 comments on commit 75e6e48

Please sign in to comment.