Skip to content

[Bug] UnicodeDecodeError in input thread crashes application when invalid UTF-8 bytes are received #6456

@0x7c13

Description

@0x7c13

Have you checked closed issues? (https://github.com/Textualize/textual/issues?q=is%3Aissue+is%3Aclosed)
Yes

Have you checked against the most recent version of Textual? (https://pypi.org/search/?q=textual)
Yes

The bug

The input threads in LinuxDriver, LinuxInlineDriver, and WebDriver all create a strict UTF-8 incremental decoder:

e.g. linux_driver.py line 414

utf8_decoder = getincrementaldecoder("utf-8")().decode

Since no errors= argument is passed, this defaults to errors="strict". If any invalid UTF-8 byte sequence arrives from the terminal, the decoder raises
UnicodeDecodeError, which propagates up through run_input_thread() and kills the input thread. Once the input thread dies, the application loses all keyboard
and mouse handling and becomes unresponsive.

How to trigger:

  • Pasting content from a terminal with a non-UTF-8 locale (e.g. a Latin-1 or GBK encoded terminal)
  • Raw binary data leaking into stdin (e.g. from a misbehaving pipe or multiplexer)
  • A broken partial paste containing truncated multi-byte sequences

Affected files:

  • src/textual/drivers/linux_driver.py (line 414)
  • src/textual/drivers/linux_inline_driver.py (line 133)
  • src/textual/drivers/web_driver.py (line 188)

Suggested fix:

  # Before (strict — crashes on invalid bytes)
  utf8_decoder = getincrementaldecoder("utf-8")().decode

  # After (replace — substitutes U+FFFD for invalid bytes)
  utf8_decoder = getincrementaldecoder("utf-8")(errors="replace").decode
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions