Skip to content

Crash when directories 'tor-browser' and 'tor-browser_en-US' exist at the same time

After trying to set up KeePassXC browser integration, the launcher suddenly stopped working. After a bit of digging I found that it's because keepassxc writes their config file to a wrong directory that include locale and torbrowser-launcher attempts to rename it without checking first if the target name exists.

Steps to reproduce:

  1. Enter directory ~/.local/share/torbrowser/tbb/x86_64
  2. Ensure that the tor-browser directory already exists
  3. Create a directory tor-browser_{anything} (KeePassXC creates tor-browser_en-US after enabling Tor browser integration)
  4. Run torbrowser-launcher from the terminal and receive a similar output:
By Micah Lee, licensed under MIT
version 0.3.6
https://github.com/micahflee/torbrowser-launcher
Traceback (most recent call last):
  File "/usr/bin/torbrowser-launcher", line 30, in <module>
    torbrowser_launcher.main()
  File "/usr/lib/python3/dist-packages/torbrowser_launcher/__init__.py", line 76, in main
    common = Common(tor_browser_launcher_version)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/torbrowser_launcher/common.py", line 62, in __init__
    self.torbrowser12_rename_old_tbb()
  File "/usr/lib/python3/dist-packages/torbrowser_launcher/common.py", line 187, in torbrowser12_rename_old_tbb
    os.rename(abs_filename, self.paths["tbb"]["dir_tbb"])
OSError: [Errno 39] Directory not empty: '/home/xav/.local/share/torbrowser/tbb/x86_64/tor-browser_en-US' -> '/home/xav/.local/share/torbrowser/tbb/x86_64/tor-browser'

Patch content

diff --git a/torbrowser_launcher/common.py b/torbrowser_launcher/common.py
index e2aa39f..4308c04 100644
--- a/torbrowser_launcher/common.py
+++ b/torbrowser_launcher/common.py
@@ -168,7 +168,7 @@ class Common(object):
 
     # Tor Browser 12.0 no longer has locales. If an old TBB folder exists with locals, rename it to just tor_browser
     def torbrowser12_rename_old_tbb(self):
-        if not os.path.exists(self.paths["tbb"]["dir"]):
+        if not os.path.exists(self.paths["tbb"]["dir"]) or os.path.exists(self.paths["tbb"]["dir_tbb"]):
             return
         for filename in os.listdir(self.paths["tbb"]["dir"]):
             abs_filename = os.path.join(self.paths["tbb"]["dir"], filename)