Skip to content
10 changes: 10 additions & 0 deletions flow/record/fieldtypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
13 changes: 9 additions & 4 deletions tests/record/test_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 = "<test/a a_string='hello' common='world' a_count=10>\n"
assert out == expected

Expand All @@ -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:
Expand All @@ -330,8 +335,8 @@ def isatty() -> bool:
writer = RecordPrinter(getattr(sys.stdout, "buffer", sys.stdout))
writer.write(record)

out, err = capsys.readouterr()
expected = "<test/a name='Ré\\udceamy'>\n"
out, _ = capsys.readouterr()
expected = "<test/a name='Ré\\udceamy' value='C:\\äÄ\\udce4'>\n"
assert out == expected


Expand Down
Loading