- 
                Notifications
    
You must be signed in to change notification settings  - Fork 39
 
Description
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 valueSpecial 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
🙂