diff --git a/flow/record/fieldtypes/__init__.py b/flow/record/fieldtypes/__init__.py index 95f62b8b..ed1337f9 100644 --- a/flow/record/fieldtypes/__init__.py +++ b/flow/record/fieldtypes/__init__.py @@ -722,6 +722,16 @@ class posix_path(pathlib.PurePosixPath, path): class windows_path(pathlib.PureWindowsPath, path): def __repr__(self) -> str: s = str(self) + # Only use repr() if we have surrogates that need escaping + try: + s.encode("utf-8") + except UnicodeEncodeError: + # Has surrogates - use repr but fix the over-escaping + s = repr(s)[1:-1] # This escapes surrogates as \udcXX + s = s.replace("\\\\", "\\") # Fix double backslashes + s = s.replace("\\'", "'") # Fix over-escaped quotes + s = s.replace('\\"', '"') # Fix over-escaped double quotes + quote = "'" if "'" in s: if '"' in s: diff --git a/tests/record/test_record.py b/tests/record/test_record.py index ff46904a..4a507de2 100644 --- a/tests/record/test_record.py +++ b/tests/record/test_record.py @@ -29,6 +29,7 @@ set_ignored_fields_for_comparison, ) from flow.record.exceptions import RecordDescriptorError +from flow.record.fieldtypes import windows_path from flow.record.stream import RecordFieldRewriter if TYPE_CHECKING: @@ -307,7 +308,7 @@ def isatty() -> bool: writer = RecordPrinter(getattr(sys.stdout, "buffer", sys.stdout)) writer.write(record) - out, err = capsys.readouterr() + out, _ = capsys.readouterr() expected = "\n" assert out == expected @@ -317,9 +318,13 @@ def test_record_printer_stdout_surrogateescape(capsys: pytest.CaptureFixture) -> "test/a", [ ("string", "name"), + ("path", "value"), ], ) - record = Record(b"R\xc3\xa9\xeamy") + record = Record( + b"R\xc3\xa9\xeamy", + windows_path(b"\x43\x3a\x5c\xc3\xa4\xc3\x84\xe4".decode(errors="surrogateescape")), + ) # fake capsys to be a tty. def isatty() -> bool: @@ -330,8 +335,8 @@ def isatty() -> bool: writer = RecordPrinter(getattr(sys.stdout, "buffer", sys.stdout)) writer.write(record) - out, err = capsys.readouterr() - expected = "\n" + out, _ = capsys.readouterr() + expected = "\n" assert out == expected