Skip to content

Patch unicodedecodeerror in HEAR #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions multicast/hear.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,12 @@ def handle(self):
Overrides the base class method to define how incoming data is handled.

By default:
Processes the incoming data from the client, logs the messages,
and sends a response back. If the data contains the
keyword "STOP", it raises a `RuntimeError` to
initiate server shutdown.
Processes the incoming data from the client, logs the messages,
and sends a response back. If the data contains the
keyword "STOP", it raises a `RuntimeError` to
initiate server shutdown.
Silently ignores any UnicodeDecodeError when decoding data.
Returns early if data or socket is None.

Minimal Acceptance Testing:

Expand Down Expand Up @@ -426,7 +428,10 @@ def handle(self):
if data is None or not sock:
return # nothing to do -- fail fast.
else:
data = data.decode('utf8') if isinstance(data, bytes) else str(data)
try:
data = data.decode('utf8') if isinstance(data, bytes) else str(data)
except UnicodeDecodeError: # pragma: no cover
return # silently ignore invalid UTF-8 data -- fail quickly.
if (_sys.stdout.isatty()): # pragma: no cover
print(f"{self.client_address[0]} SAYS: {data.strip()} to ALL")
if data is not None:
Expand Down
31 changes: 31 additions & 0 deletions tests/test_hear_data_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,37 @@ def test_handle_none_data(self):
"Socket should not be used when data is None"
)

def test_handle_with_invalid_utf8_data(self):
"""Test that HearUDPHandler silently ignores invalid UTF-8 data.

This test verifies that:
1. The handler continues processing when receiving invalid UTF-8 data
2. No exception is raised
3. The handler silently ignores the decoding error
"""
_fixture_port_num = self._always_generate_random_port_WHEN_called()
self.assertIsNotNone(_fixture_port_num)
self.assertIsInstance(_fixture_port_num, int)
_fixture_client_addr = ("224.0.0.1", _fixture_port_num)
data = b'\xff\xfe\xfd\xfc' # Invalid UTF-8 bytes
sock = multicast.genSocket()
handler = multicast.hear.HearUDPHandler(
request=(data, sock),
client_address=_fixture_client_addr,
server=None
)
try:
# Should silently ignore invalid UTF-8 data
handler.handle() # If no exception is raised, the test passes
# Verify handler state after processing invalid data
self.assertIsNone(handler.server) # Server should remain None
self.assertEqual(handler.client_address, _fixture_client_addr)
except Exception as e:
self.fail(f"Handler raised an unexpected exception: {e}")
finally:
# Clean up socket
multicast.endSocket(sock)


if __name__ == '__main__':
unittest.main()
Loading