Skip to content

Uninitialized variable in _handle_io #237

@gdesmar

Description

@gdesmar

Describe the bug
The writer variable is not initialized if _handle_io raises an exception before or during the call to _threaded_copy_data and causes a second exception.

To Reproduce
Here is an example:

>>> import gnupg
>>> gpg = gnupg.GPG()
>>> gpg.decrypt_file("8a2639de6c5ce59b4e8d048616b25b681b3a08715a92184334d07dbdd2b006ea", passphrase='I’ll')
Traceback (most recent call last):
  File ".../gnupg.py", line 1288, in _handle_io
    _write_passphrase(stdin, passphrase, self.encoding)
  File ".../gnupg.py", line 185, in _write_passphrase
    passphrase = passphrase.encode(encoding)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2019' in position 1: ordinal not in range(256)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../gnupg.py", line 2121, in decrypt_file
    self._handle_io(args, fileobj_or_path, result, passphrase, binary=True)
  File ".../gnupg.py", line 1293, in _handle_io
    writer.join(0.01)
    ^^^^^^
UnboundLocalError: cannot access local variable 'writer' where it is not associated with a value

Special attention needs to be paid to the apostrophe in the passphrase, which is not a simple ' but a . There is a problem testing the password as it does not encode to latin-1, but once the function _write_passphrase raises an exception, the code in _handle_io goes to the finally block and tries to close the writer which never got initialized. Depending on the setup, the second exception can lightly conceal the real exception.
The specific gpg file is not important and it should be possible to reproduce with any file.

Expected behavior
From the comment found in __init__ I can see that since 0.3.7 the encoding is always set to latin-1. I would expect the library to raise an exception, but to have the exception related to the UnicodeEncodeError instead, as shown by the previous code snippet.

Environment
Debian 11
Python 3.11.7
python-gnupg==0.5.2

🙂

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions